Skip to content

Feat/genspec tui - #38

Merged
fredbi merged 3 commits into
go-openapi:masterfrom
fredbi:feat/genspec-tui
Jul 31, 2026
Merged

Feat/genspec tui#38
fredbi merged 3 commits into
go-openapi:masterfrom
fredbi:feat/genspec-tui

Conversation

@fredbi

@fredbi fredbi commented Jun 12, 2026

Copy link
Copy Markdown
Member

Change type

Please select: 🆕 New feature or enhancement|🔧 Bug fix'|📃 Documentation update

Short description

Fixes

Full description

Checklist

  • I have signed all my commits with my name and email (see DCO. This does not require a PGP-signed commit
  • I have rebased and squashed my work, so only one commit remains
  • I have added tests to cover my changes.
  • I have properly enriched go doc comments in code.
  • I have properly documented any breaking change.

@fredbi
fredbi force-pushed the feat/genspec-tui branch 8 times, most recently from 9c48c39 to 0c2351b Compare June 17, 2026 18:53
@fredbi
fredbi force-pushed the feat/genspec-tui branch from 0c2351b to 0d38092 Compare June 26, 2026 18:35
@fredbi
fredbi force-pushed the feat/genspec-tui branch 2 times, most recently from f4d9bb4 to bf1e085 Compare July 31, 2026 12:27
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

❌ 6 Tests Failed:

Tests completed Failed Passed Skipped
1977 6 1971 2
View the top 3 failed test(s) by shortest run time
github.com/go-openapi/codescan/cmd/genspec-tui/internal/ux::TestE2E_NoMarkLandsPastItsLine
Stack Traces | 0s run time
Failed
github.com/go-openapi/codescan/cmd/genspec-tui/internal/ux::TestRenderDiagnostics
Stack Traces | 0s run time
Failed
github.com/go-openapi/codescan/cmd/genspec-tui/internal/ux::TestRenderDiagnostics/soft_diagnostics
Stack Traces | 0s run time
Failed
github.com/go-openapi/codescan/cmd/genspec-tui/internal/ux::TestE2E_GoSyntaxLeavesTheSourceIntact
Stack Traces | 0.04s run time
Failed
github.com/go-openapi/codescan/docs/examples/concepts/polymorphism::TestPolymorphismDiscovery
Stack Traces | 0.19s run time
Failed
github.com/go-openapi/codescan/cmd/genspec-tui/internal/ux::TestE2E_DiagnosticMarksTheOffendingKeyword
Stack Traces | 14.1s run time
Failed

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

fredbi and others added 3 commits July 31, 2026 15:35
A terminal front-end for codescan: point it at a package tree and it shows the
Go source and the Swagger spec that source produces, side by side, rescanning
as the files change. It is a self-contained module under cmd/genspec-tui so the
library takes on none of its dependencies.

Four panes — a source tree, a file view, the generated spec, and the scanner's
diagnostics — over a debounced watcher that rescans on save and re-renders
without losing your place. The spec pane renders JSON or YAML, searches, and
keeps a line cursor that survives a rebuild by remembering the NODE it was on
rather than the line number, which changes on every render.

Cross-reference navigation is the reason the two halves sit together. The
scanner reports, for each spec node it produces, the source position of the Go
construct that produced it; that stream is indexed both ways against the exact
bytes each pane draws, so a spec node resolves to its source and a source line
resolves to the node it produced. From there: follow mode, where one pane
drives and the other mirrors; a one-shot jump; find-references over a
definition's use sites; go-to-definition on a local $ref; and a gutter marking
which lines actually lead somewhere.

Because every one of those is keyed on a line number, the file, the buffer, the
indexes and the marks must agree on what a line is. The editor widget treats a
lone CR as a line break, so a file with Windows endings would otherwise load as
twice as many lines with a blank between each, and every coordinate below the
first CR would name a line a growing distance from the one meant. Content is
normalised to LF on the way in, giving all four one shared notion.

The linker answers honestly when it cannot help. A node with no anchored
ancestor was never produced from code — an overlay node legitimately has no
origin — and says so instead of jumping somewhere plausible. A node that
resolves but is not rendered in the active view says that instead. With unsaved
edits in the buffer every position below the edit has moved, so follow mode
shows a staleness badge until a save triggers a rescan.

Both panes are syntax-highlighted with no highlighting library involved. The
spec pane reuses the lexer that already builds its line-to-pointer index, so
classification is a third product of one walk. The source pane uses go/scanner,
which is error tolerant, so a buffer you are halfway through editing still
highlights. Comments there get three classes rather than one, because in a spec
generator a comment is not uniformly commentary: a `swagger:` line is the
annotation that declares the thing, a leading grammar keyword is grammar the
parser acts on, and the rest is prose. Keyword recognition goes through the
parser's own table, so aliases and letter case come for free. The scanner's
diagnostics are drawn on the token they name, so a finding is visible on the
line you are reading rather than only in the pane below.

Highlighting composes by (line, column, kind) spans rather than pre-coloured
strings: the raw text is truncated at rune boundaries first and styled last,
which is the only order in which a narrow pane cannot cut through an escape
sequence. Positions are translated between the file's byte columns and the
buffer's rune columns, since the editor widget substitutes spaces for tabs.

Scanner options are editable at runtime through a grouped overlay that marks a
toggle moot when the option it depends on is off, and every value-typed option
is a CLI flag. A key-bindings overlay behind `h` or `?` documents the lot, with
a header chip pointing at it. Diagnostics are navigable and jump to source like
every other pane, and every navigable pane pages.

Known limits are documented in the module README rather than left to be
discovered: editing is a plain textarea that normalises tabs to spaces and
CRLF endings to LF when saving, edit mode is not highlighted, and $ref
resolution is a site index rather than a resolver, so chains and external refs
are reported rather than chased.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Brings the new module into the workspace so `go test work ./...` covers it and
the shared CI runs it, rather than the module carrying a bespoke workflow of
its own.

The `go` directive moves to 1.25.8 across every module and the workspace file.
That is not a preference: the JSON and YAML lexers in go-openapi/core declare
go 1.25.8, and a module's directive must be at least its dependencies'. Only
cmd/genspec-tui requires those lexers, so only it is forced; the rest are
aligned to it deliberately, and the workspace file must be at least the highest
of them. The floor moves by a patch rather than a minor, so the supported Go
minors are unchanged and the toolchain-independence job's oldstable assumption
still holds — its note is updated to record which value it now depends on and
why, since it named the old one.

Four linters are excluded for this module by path, each with its reason: the
layout arithmetic that mnd flags is code where the number is the explanation,
the switches exhaustive flags read open-ended keyboard and mouse input rather
than a closed domain, and unparam flags helpers that keep a general signature.
The library keeps all of them. Everything else the linters found is fixed
rather than excused, including the module-local ordering drift.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
.gitattributes already states the rule — golden fixtures must keep LF endings
on every platform so byte comparison does not trip on a checkout defaulting to
core.autocrlf=true — but listed only *.json and two golden directories. The
polymorphism tutorial's diagnostics golden is a .txt, so on Windows it was read
back with CRLF and compared against a string joined with LF:

    expected: "...discovered as a subtype of...\r\n"
    actual:   "...discovered as a subtype of...\n"

Extending the pattern to *.txt covers it. The three .txt files tracked here are
that golden, the spellcheck wordlist and a vendored README, so the wider glob
costs nothing and stops the next golden of that kind from slipping through.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
@fredbi
fredbi force-pushed the feat/genspec-tui branch from bf1e085 to e25ad92 Compare July 31, 2026 14:08
@fredbi
fredbi merged commit 121e6ed into go-openapi:master Jul 31, 2026
23 of 24 checks passed
@fredbi
fredbi deleted the feat/genspec-tui branch July 31, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant