Feat/genspec tui#38
Open
fredbi wants to merge 129 commits into
Open
Conversation
8c152b5 to
9002353
Compare
go-swagger issue #3214 reported that a struct field referencing a named primitive type (e.g. `State State` -> `type State string`) whose doc comment carried both prose and an inline `enum:` annotation was only parsed for title/description, with the `enum:` declaration line wrongly folded into the description instead of parsed into enum values. The grammar2 migration already fixed this. This adds a regression lock: the referenced primitive is emitted as its own definition with `enum` parsed and the prose preserved (single-line -> title; multi-paragraph -> title + description), and the `enum:` line never leaks into either. Holds for ScanModels on and off. - fixtures/bugs/3214/types.go: the issue repro (Order/State) plus a multi-paragraph Currency variant pinning description survival. - internal/integration/coverage_bug_3214_test.go: asserts the parsed shape directly and compares against a golden. - fixtures/integration/golden/bugs_3214_schema.json: captured golden. * contributes go-swagger/go-swagger#3214 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #3107 reported that `generate spec -m` (scan-models) emitted a swagger:model struct as an empty definition carrying only `x-go-package`, with all fields dropped. This no longer reproduces. This adds a regression lock: under ScanModels the model is emitted with `type: object` and its full property set. The fixture places the model in its own package, referenced cross-package by a route response body, so it also exercises type resolution through the import graph — the v0.30.5 trigger where the model package was resolved by reference rather than directly scanned. Modern go/packages loading resolves the type fully. - fixtures/bugs/3107/model: the MyStruct swagger:model. - fixtures/bugs/3107/api: route whose response references it cross-package. - internal/integration/coverage_bug_3107_test.go: asserts the non-empty shape directly and compares against a golden. - fixtures/integration/golden/bugs_3107_schema.json: captured golden. * contributes go-swagger/go-swagger#3107 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…er#3100) go-swagger issue #3100 reported that a parameter declared with `in: formData` inside an inline `swagger:route` annotation lost its `in` field in the generated spec — the scanner only recognised `form` — so the parameter rendered with name/type/description but no `in`. This no longer reproduces. This adds a regression lock: the grammar YAML body parser preserves `in: formData` verbatim. The fixture uses the reporter's `+name:` flush form with two formData params plus a query param so the golden proves `in` survives for formData specifically, alongside other locations. - fixtures/bugs/3100/api.go: inline swagger:route with formData params. - internal/integration/coverage_bug_3100_test.go: asserts every param carries `in` and the formData values, plus golden compare. - fixtures/integration/golden/bugs_3100_schema.json: captured golden. * contributes go-swagger/go-swagger#3100 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…796) go-swagger issue #796 reported that `generate spec -m` (scan-models) emitted definitions for types carrying no `swagger:model`: an un-annotated interface (Handler) and a `swagger:parameters` struct (pingParams) both leaked into `definitions`. The parameter struct also folded its `in: path` annotation line into the property description. Neither reproduces. This adds a regression lock: under ScanModels only the swagger:model type (pingResponse) is emitted; the interface is dropped and the parameter struct renders as an operation parameter with a clean description and a real `in: path` field. - fixtures/bugs/796/main.go: faithful repro (meta + model + bare interface + parameters struct + route). - internal/integration/coverage_bug_796_test.go: asserts the absence of the extra definitions and the clean parameter, plus golden compare. - fixtures/integration/golden/bugs_796_schema.json: captured golden. * contributes go-swagger/go-swagger#796 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #3035 reported that a swagger:response whose body is an anonymous inline struct emitted only the response description with no schema at all — dropping the field-level Example/Required and property descriptions. This no longer reproduces: the inline body struct now produces a full object schema with its required set, property descriptions, and per-field example (examples in responses work). Confirmed with and without a blank line after the body field's leading prose. Documented delta: the schema-level description sourced from the body field's leading comment is not emitted. No codescan path surfaces a body field's prose as the schema description (verified against all response goldens) and the blank line does not enable it — consistent behaviour, not a regression. The test asserts that delta explicitly so a future change to it is a conscious decision. - fixtures/bugs/3035/response.go: the issue repro (inline body struct with field-level Example/Required), blank-line annotation form. - internal/integration/coverage_bug_3035_test.go: asserts the schema and the field example, plus golden compare. - fixtures/integration/golden/bugs_3035_schema.json: captured golden. * contributes go-swagger/go-swagger#3035 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #958 ("how to specify sample values in user structs")
noted that a field-level `default:` (and example) was carried for a plain
builtin field but dropped when the field used a named/defined type such
as `type SpecificType string`.
This no longer reproduces: both default and example survive for
defined-type fields. Because a $ref cannot carry sibling keywords, they
ride the override arm of an allOf compound — the same draft-4-compliant
shape used for description/example on $ref'd fields (#3125).
- fixtures/bugs/958/types.go: a plain-field model and a defined-type
model, each carrying default and example.
- internal/integration/coverage_bug_958_test.go: asserts the inline
placement for the plain field and the allOf override arm for the
defined-type field, plus golden compare.
- fixtures/integration/golden/bugs_958_schema.json: captured golden.
* contributes go-swagger/go-swagger#958
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…796 sibling #1109) go-swagger issue #1109 reported "invalid swagger.json when returning response is model": a route with `200: order`, where `order` is a model (not a named response), produced a dangling `$ref: #/responses/order` and no definitions. Per @casualjim this is expected behaviour, not a bug. Verified: the invalid-spec symptom no longer occurs. `200: <name>` resolves as (1) a named response → `$ref: #/responses/<name>`, else (2) a scanned model definition (requires -m) → promoted to a body `$ref: #/definitions/<name>`, else (3) dropped with a warning diagnostic rather than emitting an invalid ref. So the OP's exact `200: order` form now works with -m via the definition-fallback, as does casualjim's `200: body:order`. This is primarily a documentation matter (the -m requirement and the name-resolution order); flagged "Need doc" in the backlog. This commit locks both working forms as a regression witness. - fixtures/bugs/1109/responseref: OP's `200: order` form (definition fallback). - fixtures/bugs/1109/bodyref: casualjim's `200: body:order` form. - internal/integration/coverage_bug_1109_test.go: asserts a body schema $ref to the order definition (no dangling response ref, definition present) for both forms, plus golden compare. - fixtures/integration/golden/bugs_1109_{responseref,bodyref}_schema.json. * contributes go-swagger/go-swagger#1109 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #624 ("Model responses don't get included in
definitions", a regression from #596) reported that a model used only as
a field of a response body was not added to definitions. The reporter's
repro is the booking API, which is already in-repo as
fixtures/goparsing/bookings/api.go and asserted by
TestAppScanner_Definitions.
Verified no longer reproduces: the model-discovery rule works as the
reporter expected — a struct lands in definitions when swagger:model
-annotated OR referenced (transitively) by a route/response body;
un-annotated unreferenced structs are excluded. No new fixture: the
example exposes nothing the existing fixtures don't already cover (bare
`swagger:model`, body:Model responses are covered elsewhere).
This adds a doc comment cross-linking the locking test to the issue.
Primarily a documentation matter (the discovery rule); flagged "Need
doc" in the backlog for the doc-site pass.
* contributes go-swagger/go-swagger#624
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…-swagger#874)
go-swagger issue #874 reported that `swagger:response` "doesn't work with
a package prefix": a dotted name like `utils.Error` produced no response.
Root cause: the loose classification regex (rxSwaggerAnnotation) accepts
the `swagger:response` marker, so the type is classified as a response,
but the strict name matcher (rxResponseOverride) rejects `utils.Error`
(names must be plain identifiers). The two disagreed, so the annotation
was silently dropped with no feedback.
The OP's actual goal already works: cross-package types resolve
automatically and a plain response name round-trips fine. The package
prefix was a misunderstanding — response/definition names are JSON labels,
not Go-qualified identifiers, and we intentionally keep the name alphabet
to plain identifiers (opening it to `.` would invite arbitrary
characters).
The genuine defect was the silent drop. This makes the scanner WARN when
a swagger:model / swagger:response name is not a plain identifier, instead
of dropping it silently — consistent with the no-silent-fallthrough
posture elsewhere in the scanner.
- internal/parsers/{regexprs,matchers}.go: MalformedModelName /
MalformedResponseName detectors (loose arg capture vs strict override).
- internal/scanner/index.go: warnMalformedStructName, called from the
model/response classification arms (extracted to keep detectNodes under
the cognitive-complexity budget).
- internal/parsers/matchers_test.go: TestMalformedOverrideName — dotted
names flagged; bare markers, plain names, and trailing periods are not.
Primarily a documentation matter too (names are plain labels); flagged
"Need doc" in the backlog.
* contributes go-swagger/go-swagger#874
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…3213)
go-swagger issue #3213 ("Consider TypeSpec comments") asked whether doc
comments / swagger annotations attached to an individual TypeSpec inside a
grouped `type ( ... )` declaration — rather than to the enclosing GenDecl
— are parsed.
They are. This locks it with a fixture that proves per-TypeSpec capture:
two models share ONE type group, each with its own doc comment, and both
surface their distinct titles (a GenDecl-only reader could not). A grouped
swagger:enum referenced by one of them also has its const values parsed.
- fixtures/bugs/3213/api.go: two grouped models + a grouped enum.
- internal/integration/coverage_bug_3213_test.go: asserts both distinct
titles and the grouped enum values, plus golden compare.
- fixtures/integration/golden/bugs_3213_schema.json: captured golden.
* contributes go-swagger/go-swagger#3213
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #3119 ("Can not declare normal field in properties of
schema object") reported that scalar fields (limit, offset) declared
alongside an array field inside an inline swagger:operation response
schema ended up as siblings of `properties` rather than inside it.
Not a codescan defect. With consistent YAML indentation, scalar and array
properties all land correctly inside `properties` (matching the
reporter's own expected output). The reporter's input mixed tabs and
spaces, which is what broke the nesting — a YAML-indentation mistake, not
a parser bug.
No fixture: the behaviour is already exercised by the inline
swagger:operation corpus. Flagged "Need doc" in the backlog so the doc
site can warn that inline-schema YAML indentation must be consistent
(mixed tabs/spaces silently re-nests properties).
* contributes go-swagger/go-swagger#3119
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #2961 ("Improper parsing of uint enums") reported that an
`enum:` on a uint / uint64 field was emitted as strings (["1","2","3"]).
Fixed: enum values are coerced against the integer schema type, so a
`uint`/`uint64` field's `enum: 1,2,3` yields numeric `[1,2,3]`.
- fixtures/bugs/2961/api.go: uint and uint64 fields with comma-list enums.
- internal/integration/coverage_bug_2961_test.go: asserts numeric enum
values, plus golden compare.
* contributes go-swagger/go-swagger#2961
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…-swagger#3007)
go-swagger issue #3007 ("[Bug]generate spec error") reported that a
kubebuilder marker `+kubebuilder:default:=false` aborted the scan with
`strconv.ParseBool parsing "=false"`.
Fixed: the scan no longer crashes on non-swagger comment markers. Residual
(flagged Need doc): the marker is currently absorbed into the field
description rather than ignored — filtering known non-swagger markers
(kubebuilder, etc.) out of prose is a possible future enhancement, captured
as a TODO in the test.
- fixtures/bugs/3007/api.go: a field carrying a kubebuilder marker.
- internal/integration/coverage_bug_3007_test.go: asserts no scan error
and documents the description residual, plus golden compare.
* contributes go-swagger/go-swagger#3007
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…(go-swagger#3069)
go-swagger issue #3069 ("change the representation of one parameter") asked
how to make a custom-marshalled struct render with its real wire format.
codescan cannot infer a custom MarshalJSON, but a `swagger:type` override
(or encoding.TextMarshaler / swagger:strfmt) states the representation
explicitly. This witness shows ComplexType -> string making a
[]ComplexType field render as an array of strings, matching the reporter's
format. Flagged Need doc (document the override for custom-marshalled types).
- fixtures/bugs/3069/api.go: a custom-marshalled struct overridden via
swagger:type, used in a slice field.
- internal/integration/coverage_bug_3069_test.go: asserts array-of-string
items, plus golden compare.
* contributes go-swagger/go-swagger#3069
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…gger#2959)
go-swagger issue #2959 ("Unable to provide security definitions") reported
that a SecurityDefinitions block in swagger:meta crashed with "found
character that cannot start any token" — caused by TAB-indented YAML.
No longer reproduces: tab-indented SecurityDefinitions parse cleanly. This
is already covered by the existing meta fixtures (fixtures/goparsing/meta/v3
uses tab-indented SecurityDefinitions; enhancements_meta_securitydefs has a
golden), so no new fixture is added — this commit records the contribution
reference.
* contributes go-swagger/go-swagger#2959
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…2907)
go-swagger issue #2907 ("Go-Swagger not generating properties in yaml
file") reported that a response whose body is a slice of a cross-package
model (`Body []data.Movie`) emitted `items: {}` — the model's properties
were lost.
Fixed: the cross-package model is resolved, so the response schema is an
array of `$ref` to the emitted definition (with/without -m). The json:"-"
field is correctly excluded.
- fixtures/bugs/2907/{data,api}: a model in a sibling package referenced as
a []Model response body.
- internal/integration/coverage_bug_2907_test.go: asserts array-of-$ref
items and the emitted definition, plus golden compare.
* contributes go-swagger/go-swagger#2907
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…agger#2917) go-swagger issue #2917 reported `classifier: unknown swagger annotation "extendee"` when importing grpc-gateway openapiv2 options: an over-broad annotation regex matched `…openapiv2_swagger:extendee…` inside a generated comment and aborted the scan. Fixed: the current regex only matches `swagger:` at start-of-line or after whitespace/slash, so an embedded `_swagger:extendee` is not treated as an annotation. The scan completes. - fixtures/bugs/2917/api.go: a protobuf-style comment carrying `openapiv2_swagger:extendee`. - internal/integration/coverage_bug_2917_test.go: asserts no scan error, plus golden compare. * contributes go-swagger/go-swagger#2917 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…2912) go-swagger issue #2912 asked why parameter names come from Go field names rather than the `form:"..."` struct tag. Works-as-designed: codescan derives parameter names from the `json:` tag (the established convention), falling back to the Go field name. The `form:` tag (a binding-framework concern) is not consulted. Confirmed: a field with only `form:"sort_key"` is named `SortKey`, while adding `json:"sort_key"` names it `sort_key`. No code change; no fixture (json-tag naming is already exercised by the named-struct-tags corpus). Flagged "Need doc": document that parameter names derive from json tags, and the form-tag workaround. * contributes go-swagger/go-swagger#2912 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Mirror the go-openapi/runtime doc-site pattern to bootstrap https://go-openapi.github.io/codescan/: - hack/doc-site/hugo/: Hugo config, local runner (gendoc.go), the `code` shortcode + partials, and the shared go-openapi branding assets - .github/workflows/update-doc.yml: build + deploy to GitHub Pages - docs/doc-site/: home, usage (getting-started, examples, reference) and project (README, LICENSE) content - docs/examples/: a separate, test-covered Go module whose annotated petstore is scanned by codescan.Run; doc pages pull snippets straight from source via `// snippet:` markers, and the example page renders a golden swagger.json the test verifies (UPDATE_GOLDEN=1 to regenerate) Adding docs/examples makes this a multi-module repo, so: - switch go-test.yml to the go-test-monorepo.yml reusable workflow, so the examples module is built, tested and linted in CI alongside the root - disable gomoddirectives in .golangci.yml: local replace directives are needed for proper releasing of a multi-module repo Reference material under docs/*.md is linked from usage/reference for now; migrating it into first-class site pages is tracked separately. Signed-off-by: Frederic BIDON <fredbi@yahoo.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lidations (go-swagger#2985)
go-swagger issue #2985 asked for minProperties / maxProperties (the
reporter's "minAttributes/maxAttributes") on swagger:model object types.
code-to-spec lacked them: they were not grammar keywords, so the
annotation lines were swallowed into the model description and no
validation was emitted on the object schema (spec-to-code already had
them). This adds them, the sibling patternProperties keyword, and wires
the wrong-context diagnostics that were previously missing for all three.
minProperties / maxProperties:
* new CtxSchema-only asInt() grammar keywords (object validations have no
SimpleSchema form), mirroring minItems/maxItems
* SchemaValidations.SetMin/MaxProperties wired through both schema-dispatch
paths (schemaIntegerHandler + walker.go onInteger)
* the validations.keywordTypeRules object shape-rule was already present
patternProperties:
* new CtxSchema-only asString() keyword whose argument is a regex; each
line adds a `regex -> {}` entry to schema.patternProperties
* the regex gets the same RE2-hygiene check as `pattern`: a non-compiling
value emits CodeInvalidAnnotation but is preserved (never dropped) — the
shared check is factored into warnInvalidRE2
Wrong-context diagnostics (previously silent):
* non-object model — a top-level scalar swagger:model dispatches its doc
block before the Go type is resolved, so the inline checkShape saw an
empty type and applied object/array/string/number keywords anyway. New
handlers.RecheckSchemaShape, called from schema.Build after buildFromDecl,
strips validations illegal for the resolved type and emits
CodeShapeMismatch. Done as a post-hoc strip rather than a dispatch
reorder to avoid changing default:/enum: coercion timing — zero golden
churn.
* SimpleSchema sites — the param/header/items dispatchers silently dropped
full-Schema-only object keywords. handlers.Integer now takes a diag and,
with UnsupportedSimpleSchemaString, emits CodeUnsupportedInSimpleSchema
for CtxSchema-only keywords (predicate isFullSchemaOnly, which correctly
excludes param-legal keywords like `in:`).
Tests/fixtures:
* bugs/2985 — object model asserting minProperties:1 / maxProperties:10
and no description leak
* enhancements/pattern-properties — valid + invalid-regex models
* enhancements/object-keywords-context — kept / shape-mismatch /
simple-schema across all three contexts
* keyword docs (docs/keywords.md), schema README (§decl-shape-recheck),
validations README type-domain table updated
* closes go-swagger/go-swagger#2985
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…#2875)
go-swagger issue #2875 ("AllOf member does not generate an external $ref
object"): an embedded struct annotated `swagger:allOf` inlined the embedded
type's properties instead of emitting an `allOf: [{$ref}]`.
Fixed: the member is emitted as an `allOf` arm referencing the embedded
model's definition via $ref.
- fixtures/bugs/2875/api.go: AllOfModel embedding SimpleOne with swagger:allOf.
- internal/integration/coverage_bug_2875_test.go: asserts the allOf $ref arm
and the emitted SimpleOne definition, plus golden compare.
* contributes go-swagger/go-swagger#2875
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #2899 ("Example not being added to schema for body string
params"): an `example:` on an inline body parameter of primitive type was
dropped.
Fixed: the example is carried onto the body parameter's schema. A known
residual (quirk F8) is tracked separately: a quoted string example
(`example: "123456"`) currently retains its surrounding quotes; the test
asserts the current value and references F8.
- fixtures/bugs/2899/api.go: inline body param with type:string + example.
- internal/integration/coverage_bug_2899_test.go: asserts the example is on
the param schema (the fix); documents the F8 quoting residual.
* contributes go-swagger/go-swagger#2899
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #2897 ("with go1.20 swagger missing definitions and refs")
reported missing definitions/refs from a debian-repo swagger binary, while a
self-built binary worked.
Not a codescan logic bug: the reporter's example (a swagger:response with a
struct Body) produces the definition and $ref correctly in the current
scanner. The failure was environmental (a stale/mismatched packaged binary
vs go version), not a scanner defect. No fixture (response-struct-body
resolution is already covered by #1109 / #2907).
* contributes go-swagger/go-swagger#2897
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #2898 reported that `[]interface{}` changed in 0.30 to emit
`items: {}` instead of `items: {type: object}`.
Works-as-designed: `items: {}` (an empty schema = "any type") is the correct
representation for a slice of `interface{}` — `{type: object}` would wrongly
restrict the elements to objects. The 0.30 change is a correctness
improvement, not a regression. No code change; flagged Need doc to explain
the rationale.
* contributes go-swagger/go-swagger#2898
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…wagger#2909)
go-swagger issue #2909 ("Regular cannot generate swagger automatically"): a
route path with an inline regex segment (gorilla/chi style, e.g.
{id:[0-9]+}) was silently dropped. rxPath's alphabet has no `[`/`]`, so the
swagger:route / swagger:operation line failed to match, the scanner never
collected the path, and nothing was emitted — with no diagnostic.
OpenAPI 2.0 path templating follows RFC 6570 URI Template Level-1 expansion
only (simple `{name}` substitution); it cannot express a regex constraint.
go-openapi's runtime path-templating middleware is Level-1 too. So rather
than silently dropping the route, strip the `:regex` constraint and warn.
Fix:
* parsers.stripPathParamRegex rewrites `{name:regex}` -> `{name}` on the
comment line BEFORE the rxRoute/rxOperation match. Brace matching is
depth-aware, so regex quantifiers carrying their own braces
({id:[0-9]{2,4}}) are handled. No rxPath alphabet change needed; the
original line is preserved for the description block.
* ParsedPathContent gains Pos + StrippedParams to carry the strip info out
of the scanner.
* common.Builder.WarnStrippedPathRegex (shared by the routes and operations
builders) emits a parse.invalid-annotation warning naming the affected
params and explaining the RFC 6570 Level-1 limitation.
Result: /items/{id:[0-9]+} now emits as /items/{id} with the operation
intact, plus a warning that the constraint was dropped.
Tests/fixtures/docs:
* bugs/2909 — asserts the route now emits as /items/{id} and warns
* enhancements/path-regex-stripping — swagger:route (multi-param),
swagger:operation (nested-brace quantifier), and a plain {id} control
that raises no warning
* unit table-test for stripPathParamRegex (simple / slash-class / nested /
multiple / no-colon control / unbalanced / empty-name)
* docs/annotations.md swagger:route path section documents RFC 6570 Level-1
and the strip behaviour
* closes go-swagger/go-swagger#2909
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #2802 ("Error generating spec if swagger:model is a
generic struct"): an instantiated generic (`WrappedRequest[Request]`)
panicked with "can't determine refined type T (*types.TypeParam)".
No longer panics: the instantiated type resolves its argument
(`Body.Body -> $ref: Request`); the uninstantiated generic's free type
param `T` is skipped with a warning (no spec representation), and the scan
completes.
- fixtures/bugs/2802/api.go: a generic struct + an instantiated alias.
- internal/integration/coverage_bug_2802_test.go: asserts the instantiated
type argument resolves to a $ref, plus golden compare.
* contributes go-swagger/go-swagger#2802
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…swagger#2837)
go-swagger issue #2837 ("Responses defined in routes break with go 1.19
formatting"): gofmt rewrites a route's `+ name:` parameter bullet to
`- name:`, which used to break parsing.
Both forms now parse to the same parameter. The fixtures are intentionally
the authored `+` form and the gofmt-canonical `-` form (fixtures/ is
excluded from the formatters); the test asserts they yield identical
parameters.
- fixtures/bugs/2837a (+ form) and 2837b (- / gofmt-canonical form).
- internal/integration/coverage_bug_2837_test.go: asserts both forms parse
to the same body param and golden-compares the gofmt-canonical output.
* contributes go-swagger/go-swagger#2837
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #2860 ("Models do not show fields from the struct")
reported that `-m` on the petstore fixture emitted definitions with only
title/x-go-name and no properties/required.
No longer reproduces: the petstore models emit their full fields, required
sets, and nested item schemas. Already covered by the petstore goldens
(petstore_schema_Order.json etc. and TestAppScanner_*). No new fixture;
contribution recorded via an empty commit.
* contributes go-swagger/go-swagger#2860
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…(go-swagger#1713)
Response examples keyed by mime type (examples: {application/json: {...}})
are supported in the swagger:operation YAML body. Lock with a witness. (The
struct-based swagger:response example-by-mime form remains forthcoming
feature §10 / #2871.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* contributes go-swagger/go-swagger#1713
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
#1670 reports "yaml: did not find expected key" during generate spec with no way to tell which annotation's YAML is at fault. Under-specified (no repro) and really a diagnostic-quality concern (locate the offending block). Parked in the Poison queue; relates to fail-loud diagnostics (§8). No code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * contributes go-swagger/go-swagger#1670 Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…agger#1712)
#1712 ("couldn't load packages ... CacheLineSize/ArchFamily redeclared") is
an environmental package-load failure (duplicate arch-specific declarations
in a dependency), not a scanner-logic bug. Under-specified; parked in the
Poison queue. No code.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* contributes go-swagger/go-swagger#1712
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…#1088)
An array IS valid in a non-body parameter / response header, but its
items form a Swagger 2.0 SimpleSchema, which may not contain a $ref. A
named object element ([]Ele under in: query, or an array-of-object
response header) resolved to `items: {$ref: #/definitions/Ele}`, which
the Swagger 2.0 editor rejects.
Root cause: the SimpleSchema catch-at-exit validator
(schema.validateSimpleSchemaOutcome) only inspected the top-level
target. For an array element the $ref lives one level down, on
param.Items / header.Items, whose adapter resolvers.ItemsTypable did not
implement schema.SimpleSchemaProbe — so the validator skipped it.
Fix: make ItemsTypable a SimpleSchemaProbe (SimpleSchemaShape / HasRef /
ResetForViolation). Each array element is built through a fresh
WithSimpleSchema sub-build whose target IS the ItemsTypable, so the
existing validator now inspects the element shape and dissolves an
illegal $ref to an empty {} with a CodeUnsupportedInSimpleSchema
diagnostic. Named primitives ([]Label) keep expanding inline to
{type: string}. ItemsTypable is shared by parameters and response
headers, so both are fixed by the one change.
Also add common.Builder.ResetPostDeclarations, called by the validator
on a ref violation: MakeRef had discovered the now-dissolved target's
decl, which would otherwise linger as an orphan definition ([]Ele no
longer drags an unreferenced Ele into definitions). This also removes a
pre-existing orphan io.Reader definition in the in-case-insensitive
golden.
Witnesses: fixtures/bugs/1088 (query []Label/[]Ele + response headers
X-Tags/X-Objs) and TestCoverage_Bug1088 (no $ref at any items level, the
empty-object dissolution, the absent orphan, the diagnostics). Golden
drift is uniformly the same correct dissolution plus the one orphan
removal. Documented in schema/README.md and common/README.md.
* contributes go-swagger/go-swagger#1088
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
… (go-swagger#1088) Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…s (go-swagger#1635)
A swagger:response or swagger:parameters struct that ANONYMOUSLY embeds a
named struct marked `in: body` must treat the embed AS the body — exactly
like a named `Body Foo` field — instead of promoting the embedded struct's
members.
Root cause (general): both responses.buildFromStruct and
parameters.buildFromStruct ran an in:body embed through the #2701
field-promotion recursion with `in: body` inherited, so the members were
promoted individually:
- responses: each promoted scalar overwrote resp.Schema, collapsing to
{type: string} (pre-#2701 the fields landed under headers, the
reporter's original complaint);
- parameters: each member became a separate in:body parameter — invalid
OAS2, which allows at most one body parameter per operation.
Fix: a response/operation has a single body, so per-field promotion under
in:body is meaningless. When the embed's inherited in: is body, the embed
IS the body, built like a named Body field (schema $refs the embedded
struct). Responses route through a new buildBodyEmbed; parameters route
the embed through processParamField (the embedded field's name is its type
name), yielding one body parameter. Other in: values keep promoting fields
(the #2701 header/query/path cases are untouched). Schemas have no in:
concept, so no analog exists there.
This also corrected the #2701 embed-inheritance witness
(embeddedBodyResponse), whose {type: string} assertion had captured this
very bug; it now asserts schema: {$ref: #/definitions/bodyPayload} with no
headers. Only that one golden drifted (embed_inheritance.json); the
parameters fix added no golden drift.
Witnesses: fixtures/bugs/1635 (TestCoverage_Bug1635 covers the anonymous
in:body embed for both a swagger:response and a swagger:parameters set,
with named-Body guard rails). Documented in responses/README.md and
parameters/README.md.
* contributes go-swagger/go-swagger#1635
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…omoted fields (go-swagger#1635) Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…ion (#1737) Two already-resolved backlog issues, locked with witnesses: - #1742 / #1735: a swagger:parameters struct in a different package from the swagger:route that references it is correctly bound to the operation by operation id. The same fixture witnesses #1735, whose nil-map panic lived in the removed legacy scan/route_params.go engine — grammar2 scans a route-with-params without panicking. - #1737: a field whose type resolves to a $ref (e.g. bson.ObjectId) drops its sibling description by default (a Swagger 2.0 limitation), but the DescWithRef option wraps it in allOf and preserves the description. * contributes go-swagger/go-swagger#1742 * contributes go-swagger/go-swagger#1735 * contributes go-swagger/go-swagger#1737 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
… (#1725, #1727) #1727 — codescan IS the library answer: `codescan.Run(*Options) (*spec.Swagger, error)` generates the spec programmatically from source. The lib-usage doc now documents this (Need-doc satisfied). #1725 — the spec version comes from `swagger:meta` `Version:`. For build-time injection, use the library and set `doc.Info.Version` after Run (or ldflags + post-process / an InputSpec overlay) — a workflow concern, works-as-designed. * contributes go-swagger/go-swagger#1727 * contributes go-swagger/go-swagger#1725 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…(#1734) Same-named structs in different packages silently merge into one #/definitions/<Name> (lossy, scan-order-dependent). Deferred as a feature (auto-disambiguation) rather than a fix — registered in forthcoming-features §14, cross-linking #2119 and the #3134 operationId-uniqueness idea. Workaround today: an explicit `swagger:model <name>`. * contributes go-swagger/go-swagger#1734 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
go-swagger issue #2791 ("swagger:parameters not working as defined in docs"):
copy-pasting the docs example produced a spec that fails validation.
Works-as-designed: codescan faithfully emits the annotations as written; the
docs example itself is invalid OAS2 — `example:` is forbidden on a non-body
(query) parameter, and `collection format: pipe` should be `pipes`. The deeply
nested [][][]string query param otherwise generates correctly (in:query,
nested items, min/max/unique). Flagged Need-doc to fix the docs example.
(A separate validation-hardening opportunity — warn on example for simple
params / validate collectionFormat — is noted but not pursued here.)
* contributes go-swagger/go-swagger#2791
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…-swagger#2762)
go-swagger issue #2762 ("codescan tests fail on go 1.18"): v1's codescan unit
tests assumed a fixed map iteration order, which changed in go 1.18.
Not applicable to this codebase: our integration tests compare against golden
JSON marshaled deterministically (stable key order via go-openapi/spec +
scantest.CompareOrDumpJSON), so there is no map-order assumption to break. No
code or test change needed.
* contributes go-swagger/go-swagger#2762
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Fixes a quirk with comments parsing, which surfaced during the go-swagger backlog verification pass. A swagger:meta YAML block written in the natural column-0 form, once gofmt runs, gains a mandatory blank "//" line under the top-level key (gofmt's doc-comment code-block rule). The resulting gofmt-canonical source then failed to scan with "found character that cannot start any token": the tab-indented children after the blank line reached the YAML sub-parser, which rejects tab indentation. This is the real residual behind go-swagger#2959-class SecurityDefinitions failures — forms that avoid the blank line, or indent the whole block uniformly, parsed fine, but gofmt rewrites the natural form into the failing one. Root: yaml.RemoveIndent keyed the dedent strip width off the literal first body line. gofmt's inserted blank line made that width zero, so RemoveIndent returned early without stripping or retabbing, leaving the children's tabs intact for the YAML parser to reject. Fix: key the strip width off the first NON-BLANK line. A leading blank line is skipped, so the gofmt-canonical form dedents and retabs identically to the uniformly-indented form. Behaviour is unchanged for bodies without leading blank lines (the first non-blank line is the first line) — the operations / meta goldens are untouched. * fixture fixtures/quirks/gofmt-meta (gofmt-clean, parses) * TestQuirk_GofmtMetaYAML flipped from documented-error to asserting the parsed securityDefinitions + golden quirk_gofmt_meta.json * direct RemoveIndent unit tests (leading-blank, column-0, all-blank) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
A `NNN: description:<text>` entry inside a swagger:route Responses block now produces a valid response carrying that description. The legacy scan engine emitted an invalid `$ref: '#/responses/'` (empty name) for this form; grammar2 parses the inline description correctly. Locked by fixtures/bugs/1828 + TestCoverage_Bug1828 + golden. * contributes go-swagger/go-swagger#1828 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…1761,#1772,#1795,#1815)
Five works-as-designed / usage-doc issues, no code change:
- #1758 — empty output ({paths:{}}) means no swagger:* annotations were found;
the spec is built from annotations, not framework routes. Scan with ./...
across all packages. (Fail-loud on empty output tracked in forthcoming §8.2.)
- #1761 — Host comes from swagger:meta `Host:`; for per-environment values set
doc.Host after Run (library) or leave it empty so the serving host is used.
- #1772 — a POST body is documented with a swagger:parameters struct field
marked `in: body`.
- #1795 — a Basic base64 Authorization header is an OAS2 security scheme
(securityDefinitions {type: basic} + security), not a manual header param.
- #1815 — go-swagger-generated server code carries swagger annotations, so the
spec can be regenerated by re-scanning those sources.
* contributes go-swagger/go-swagger#1758
* contributes go-swagger/go-swagger#1761
* contributes go-swagger/go-swagger#1772
* contributes go-swagger/go-swagger#1795
* contributes go-swagger/go-swagger#1815
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
OpenAPI 2.0 `paths` is an unordered JSON object (a Go map); declaration/display order is not meaningful in the spec and cannot be controlled by codescan. Ordering is a UI/rendering concern. Wont-fix as framed + Need-doc. * contributes go-swagger/go-swagger#1777 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…gger#1595)
A swagger:operation (or swagger:route) written in a /* */ block comment
made the whole scan fail with a YAML parse error ("did not find expected
alphabetic or numeric character").
Root cause: parsers.parsePathAnnotation (shared by both annotations)
reshapes the trailing comment content into per-line synthetic // comments
for the Remaining block. A /* */ block comment arrives as a single
*ast.Comment whose Text still carries the framing, so splitting it by \n
turned the closing */ into a synthetic `// */` line. That lands in the
YAML body as `*/`, where the leading `*` reads as a YAML alias indicator
and fails the body parse.
Fix: in parsePathAnnotation, strip the /* */ framing (stripBlockFraming)
before splitting, and shed the godoc `* ` continuation decoration per line
(stripBlockContinuation, mirroring grammar's — indentation preserved when
no `*` is present). This handles both the flush-left block style (the
reporter's) and the idiomatic `*`-decorated style, and fixes swagger:route
block comments too via the shared helper. The continuation-strip is
duplicated rather than imported so the scanner-level parsers package keeps
no dependency on the grammar sub-package.
gofmt-robustness: the fixture is committed gofmt-clean, so the flush-left
block is in gofmt's "code block" canonical form (blank line under
responses: + TAB-indented children). That form scans correctly because
this framing strip composes with yaml.RemoveIndent's dedent/retab (the F7
fix, 94ec08f); the *-decorated block is gofmt-stable. A package doc
comment warns against re-spacing the tabs.
Witnesses: fixtures/bugs/1595 (flush-left + *-decorated swagger:operation),
TestCoverage_Bug1595. No golden drift; new helpers documented via godoc.
* contributes go-swagger/go-swagger#1595
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…tions (go-swagger#1595) Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…roup-type (#1852,#1867,#1881,#1887,#1891)
Five backlog issues resolved by the grammar2 migration, each locked with a
fixture + coverage test + golden:
- #1852 — a 204 response with no doc comment still emits the OAS2-required
`description` key (legacy engine omitted it → editor.swagger.io rejected it).
- #1867 — PATCH works via both swagger:route (with a body parameter) and
swagger:operation.
- #1881 — a swagger:response whose body is a slice of a model produces a valid
`{type: array, items: {$ref}}` schema.
- #1887 — the `swagger:file` marker on a formData field emits `type: file`.
- #1891 — a swagger:model inside a grouped `type ( ... )` declaration and a
swagger:route declared inside a function body are both discovered.
* contributes go-swagger/go-swagger#1852
* contributes go-swagger/go-swagger#1867
* contributes go-swagger/go-swagger#1881
* contributes go-swagger/go-swagger#1887
* contributes go-swagger/go-swagger#1891
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…ng swagger:parameters splits across lines (#1865) - #1860 — codescan derives routes from `swagger:route`/`swagger:operation` annotations in Go source only; reading routes from a framework's non-Go .conf file is out of scope. Wont-fix as framed + Need-doc. - #1865 — a long `swagger:parameters` operation-id list is split by writing multiple `swagger:parameters` lines, each binding the struct to more operations (they accumulate). Duplicate of #1665, which already locks this. * contributes go-swagger/go-swagger#1860 * contributes go-swagger/go-swagger#1865 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…ists (go-swagger#1726) Relax list identification so markdown-style bullets (`* item`, `+ item`) are recognised exactly like the YAML-style dash form (`- item`), uniformly across the annotation language. This is NOT a full markdown here-document (that would be go-swagger#3211) — only list-marker identification. Root cause: trimContentPrefix (internal/parsers/grammar/preprocess.go) did TrimLeft(s, " \t*/"), eating a leading `* ` bullet as godoc decoration (the dash form was already preserved, for the `---` fence). Fix, in one place in the lexer pipeline so the impact is wide: drop `*` from the content-prefix strip set and normalise a leading `* `/`+ ` bullet to the canonical `- ` in trimContentPrefix. To keep block-comment `* ` continuation decoration from being mistaken for a bullet, stripLine now applies the comment-kind raw-strip (stripBlockContinuation for /* */) BEFORE the content-prefix trim. Because normalisation happens upstream on Line.Text, every downstream `- ` consumer handles markdown bullets with no per-site change: prose descriptions, Property.AsList (consumes/produces/schemes/tags) and enum bodies. Line.Raw is untouched, so YAML bodies stay strict YAML. gofmt impact (checked): gofmt rewrites `*`/`+` doc-comment bullets to `-` itself, so this only changes behaviour for non-gofmt'd source — and produces the SAME result gofmt would (verified by gofmt'ing the fixture and diffing). The fixture deliberately keeps the `*`/`+` form to witness the scanner path; fixtures/ is excluded from the gofmt formatters in .golangci.yml, matching existing non-gofmt-clean bug fixtures. Witnesses: fixtures/bugs/1726 (Widget dash guard rail; Gadget `*`, Gizmo `+` descriptions; a route with `*`-Produces / `+`-Consumes for the AsList path) + TestCoverage_Bug1726; unit tests TestNormalizeBullet / TestTrimContentPrefixBullets. No golden drift. Documented in grammar/README.md. * contributes go-swagger/go-swagger#1726 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…e YAML dash lists (go-swagger#1726) Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…ross-pkg operation params, nested ext (#1913,#1925,#1934,#1955,#1958)
Five backlog issues verified resolved by the grammar2 migration, each locked
with a fixture + coverage test + golden:
- #1913 — an interface swagger:model with `discriminator: true` emits a base
carrying `discriminator`, and swagger:allOf struct subtypes emit
`allOf: [{$ref base}, {own}]`. (Subtype discovery without -m is a separate
enhancement: forthcoming-features §15.)
- #1925 — a body parameter typed `[]map[string]interface{}` no longer aborts;
it produces a valid array-of-object-with-additionalProperties schema.
- #1934 — swagger:model / swagger:parameters declared on types INSIDE a
function body are discovered.
- #1955 — a swagger:operation can use a swagger:parameters struct defined in a
different package (matched by operation id), the swagger:operation analog of
#1742.
- #1958 — a vendor extension in the swagger:operation YAML body is preserved in
full, including nested keys named like keywords (e.g. `responses:` inside
x-amazon-apigateway-integration).
Also corrects the #1867 swagger:operation fixture/golden: its YAML body used
gofmt's tab indentation (invalid YAML), which silently dropped the operation's
responses. Reformatted to space indentation (the supported form) and the test
now asserts the operation's YAML-body response attaches.
* contributes go-swagger/go-swagger#1913
* contributes go-swagger/go-swagger#1925
* contributes go-swagger/go-swagger#1934
* contributes go-swagger/go-swagger#1955
* contributes go-swagger/go-swagger#1958
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…ed (#1960) - #1931 — to cover all sub-packages (not just doc.go), scan with `./...` or a package list; codescan loads the whole module graph in scope. Works-as- designed + Need-doc. - #1960 — struct property order is not preserved in the generated spec (definitions/properties are unordered maps); ordering is not an OAS concept and order-preserving serialization is below the planning horizon. Wont-fix as framed + Need-doc. * contributes go-swagger/go-swagger#1931 * contributes go-swagger/go-swagger#1960 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Add the single source of truth bridging each annotation keyword to the JSON-pointer location its value renders at in the produced spec (specPointers + PointerPath in keywords.go), gated by the keyword's own Contexts. Consumers read this instead of re-encoding keyword knowledge in each builder walker; it underpins the cross-ref provenance that anchors a spec node to the comment line that produced it (e.g. `maximum` → .../maximum, `version` → /info/version), with the one context-divergent case (deprecated: schema-legal but only an operation/route node) handled in the table rather than at call sites. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Expose the scanner-level data the live spec generator and its diagnostics
view need:
- OnProvenance callback (Options) + Provenance{Pointer, Pos}; ScanCtx
RecordOrigin/OriginEnabled, the deferred RecordParamOrigin/ParamOrigin
pair, and per-value positions from FindEnumValues — the source side of
the spec↔source cross-ref linker (anchors a JSON pointer to a
token.Position). Opt-in: zero cost and byte-identical spec when no sink
is wired.
- EmitDiagnostic: the OnDiagnostic stream is now deduped scan-wide (same
position, code, message). The build re-processes the same field across
passes — most visibly a swagger:parameters struct applied to several
operation ids, which rebuilds every field once per id — so a field-level
diagnostic would otherwise surface once per visit. RecordDiagnostic
delivers through it; the raw Diagnostics() accumulator is unchanged.
- force module mode (GOWORK=off in NewScanCtx) so an ambient go.work —
including this repo's own monorepo workspace — can't switch ./... scans
to workspace mode and silently empty the produced spec.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Wire the builders to emit OnProvenance anchors tying each produced spec node to its Go source position. The base pointer is threaded via schema.WithPath using advance-on-descent: applyFieldCarrier advances to the property pointer, items/additionalProperties path-join their segment, and allOf members clear it so untracked subtrees resolve to their nearest anchored ancestor — keeping every emitted pointer geometrically correct. Anchors cover definitions, properties at every depth, responses, paths/operations (a new coarse ParsedPathContent.Pos), parameters (a deferred pass, since the op isn't path-bound at parameters-build time), enum values, and swagger:meta — plus finer keyword-line anchors: each scalar validation, meta and route keyword anchors to its own `// keyword:` comment line via grammar.PointerPath (so following e.g. a `maximum` or `default` node lands on the annotation, not the field). swagger:operation keywords stay at the coarse path anchor (YAML body, no per-keyword grammar Property). The geometry invariant test asserts every emitted pointer resolves in the rendered spec; opt-in, so the spec is byte-identical when provenance is off. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
A bubbletea front-end in a separate module (cmd/genspec-tui) that scans a Go package set and renders the Swagger spec live as the source changes: source-tree, spec (JSON/YAML with search) and diagnostics panes, an fsnotify-debounced whole-scope rescan, a scanner-options popup, a read-only navigable file viewer with an opt-in editor, mouse focus/scroll and clipboard copy. Position-backed cross-reference navigation, uniform on `f` across panes: spec node ↔ Go source, source line ↔ spec node, and diagnostic → source. Each is a persistent auto-follow mode — the driver pane keeps focus and the follower mirrors on every cursor move, with both sides highlighting the linked node. Built on a caller-owned SpecIndex (rendered line ↔ JSON pointer) and SourceIndex (pointer ↔ token.Position, nearest-ancestor both ways); the diagnostics pane is navigable and follows the position carried on each grammar.Diagnostic. The spec-side index uses encoding/json/jsontext, so the module REQUIRES GOEXPERIMENT=jsonv2 to build and test. Kept out of the lean library via its own go.mod (replace → ../..); bubbletea deps stay off the library. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Tie cmd/genspec-tui into the repo as a second module via go.work, and add its CI: a monorepo test workflow, release/tag automation and dependabot, plus the lint config and .gitignore (go.work.sum is generated, not committed). The TUI module builds under GOEXPERIMENT=jsonv2 (jsontext); official binaries/wasm are pinned to go1.26 with the flag, and users building their own are warned. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Change type
Please select: 🆕 New feature or enhancement|🔧 Bug fix'|📃 Documentation update
Short description
Fixes
Full description
Checklist