Feat/feature v0.36#55
Merged
Merged
Conversation
Add Options.NameFromTags []string — an ordered list of struct-tag types
the emitted name of a schema property, parameter, or response header is
derived from. The first listed tag type that supplies a usable name wins;
a tag that is absent or carries only options (e.g. ,omitempty) is skipped
and the next is tried.
- nil/unset defaults to ["json"] (historic behaviour, byte-identical);
- an explicit empty slice consults no tag (name = Go field name);
- e.g. ["form","json"] honours gin's form: tag, falling back to json:.
Only the name is sourced this way. The encoding/json directives - (exclude),
,omitempty and ,string are always read from the json tag, independent of the
setting — json:"-" still excludes whatever names the field.
The shared resolver ParseJSONTag is generalised to ParseFieldTag(field,
goName, nameTags) and threaded through the schema, parameters and responses
builders via ScanCtx.NameFromTags(). Targeted renames (the name: keyword,
swagger:name, swagger:model {name}) and embed-nesting still take precedence.
Tested by resolvers.TestParseFieldTag (unit) and the
enhancements/name-from-tags fixture + integration coverage across the three
modes for schema properties, query parameters and response headers, with a
golden capturing the form-first spec.
* contributes go-swagger/go-swagger#1391
* contributes go-swagger/go-swagger#2912
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
OpenAPI 2.0 lets a Response object carry an `examples` map keyed by mime
type (`examples: {application/json: {…}}`). The `swagger:operation` YAML
path already emitted this for free (raw YAML unmarshalled straight into
spec.Response), but the struct-based `swagger:response` annotation path
had no way to express it — no `examples` keyword existed.
Add an `examples` grammar keyword (raw-block, CtxResponse-only) joined to
the lexer's YAML-body set so the mime→object nesting survives. The
responses builder's applyBlockToDecl now finds the `examples:` block in
the response decl comment and parses its body via yaml.UnmarshalBody into
Response.examples (map[string]any keyed by mime type). A malformed block
raises a non-fatal diagnostic and is skipped.
The singular schema `example:` decorator is untouched — OAS2 reserves the
plural `examples` for the Response object. Out of scope (unchanged):
per-request dynamic example values.
Tested by the enhancements/response-examples-by-mime fixture +
integration coverage (mime-keyed map with a JSON object and an XML string,
body $ref and description preserved) with a golden.
* contributes go-swagger/go-swagger#2871
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Document the two v0.36 features landed on this branch. Shaping the output: - New "Naming from struct tags" how-to (shaping-the-output/naming-from-tags.md) with a verified before/after example (docs/examples/shaping/naming-from-tags): the same model rendered with the default ["json"] vs ["form","json"], plus the name-only / directive caveats. Tutorials: - Refresh the "Response examples by media type" section of examples-and-defaults — it previously said the struct-based swagger:response could not emit per-mime examples, which is no longer true. Added a verified struct-response example (concepts/examples responseexamplesbymime region + golden). Keyword reference: - Add the plural `examples` keyword (raw-block, response context) to the summary table, the body-keywords detail section, and the table of contents; cross-link it from the singular schema-scoped `example`. All example fragments are generated and verified by the docs/examples module tests (regenerate with UPDATE_GOLDEN=1 go test ./...). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…discovery
Scaffolds the shared-parameters / shared-responses feature (go-swagger#2632):
spec-level shared parameters (`swagger:parameters *`), path-item parameters
(`swagger:parameters /pets`), a standalone parameter reference channel, and
shared responses (`swagger:response *`).
This commit lands the fixture harness plus the grammar/scanner layer ;
the spec-emitting builders, conflict handling, prune extension and goldens
follow in later phases.
Grammar owns the `swagger:parameters` targeting parse (it already parsed the
args into ParametersBlock; the parameters builder was the one leftover still
reading a scanner regex — a gap from the grammar migration):
- new WILDCARD token (`*`); `classifyParametersArgs` lexes `*` / `/path` /
ident args (special only in first position, so `*blah` stays an ident).
- `ParametersBlock` carries {Target, Path, Args, Dups} with de-duplication
(+ an OperationIDs() accessor); the def-vs-ref reading of Args is the
builder's, since it depends on the host declaration.
- the parameters builder reads the grammar block instead of the deleted
EntityDecl.OperationIDs(); the scanner `rxParametersOverride` is reduced to
a permissive presence gate (no arg-shape validation — the grammar diagnoses
malformed forms instead of the scanner silently dropping them).
Scanner discovers standalone reference markers: a `swagger:parameters`
marker on a func doc is a reference (per the disambiguation rule), collected
into TypeIndex.ParameterRefs and exposed via ScanCtx.ParameterRefs(); struct
markers stay definitions. Args are still parsed by the grammar on consumption.
Six fixtures under fixtures/enhancements/shared-parameters* anchor the
expected behaviour; a scan-clean smoke test guards them.
* contributes go-swagger/go-swagger#2632
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…rst conflict
Build phase: a `swagger:parameters *` struct now registers its fields at
the spec top level (#/parameters/{name}), keyed by the resolved parameter
name (so a `name:` / NameFromTags override is the key).
- parameters.Builder.Build dispatches per ParametersBlock.Target: operations
inline as before (buildIntoOperations); shared (`*`) harvests the fields via
buildShared, exposed through SharedParameters().
- spec.Builder initialises input.Parameters and merges shared registrations
with a keep-first policy: shared parameters are referenced only by short
name, so a duplicate name keeps the first and drops the later with a new
scan.shared-parameter-conflict warning — never renamed (unlike definitions).
Resolution is sorted by (package path, position, name), so the survivor is
independent of package-load order. InputSpec entries seed the map and win.
- the empty #/parameters map is omitted (omitempty), so existing goldens are
unchanged.
Tests cover top-level registration (fixture 1) and the keep-first conflict +
independent namespaces (#/parameters/Status vs #/definitions/Status, fixture 3).
* contributes go-swagger/go-swagger#2632
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Build phase: shared parameters (#/parameters/{name}) are now referenced
into operations as $refs through both channels:
- `swagger:parameters * opid …` — the definition-side convenience: the
struct registers its fields at the top level AND references them into the
listed operations. parameters.Builder exposes SharedRefOperations(); the
intents are collected during buildParameters.
- standalone `swagger:parameters opid name …` markers on a func — the
scaling channel (ScanCtx.ParameterRefs, parsed by the grammar): the first
token is the target operation, the rest are shared-parameter names.
spec.applyParameterRefs runs after the top-level map is complete and before
buildRoutes, resolving each {op, name} to a #/parameters/{name} $ref on the
operation (get-or-create), de-duplicated, in deterministic (op, name) order.
A reference to an unregistered shared parameter is dropped with a
scan.dangling-parameter-ref warning rather than emitting a dangling $ref.
Duplicate target / reference tokens the grammar drops raise
scan.duplicate-target (C1) / scan.duplicate-ref (C2) warnings. A reference
resolves by the shared parameter's resolved (overridden) name (C3).
Tests cover both reference channels (fixture 1) and the override/dedup/
dangling edge cases (fixture 5, with an added danglingRef witness).
* contributes go-swagger/go-swagger#2632
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…meters /path
Build phase: `swagger:parameters /path` now emits path-item parameters.
- on a struct, the marker inlines the struct's fields into the path-item:
parameters.buildPathItem harvests them into PathItemParameters(), keyed by
exact path.
- on a func, `swagger:parameters /path name …` adds a #/parameters/{name}
$ref to the path-item (collectPathItemRefs, from ScanCtx.ParameterRefs
with a path target).
spec.applyPathItemParameters runs after buildRoutes/buildOperations — the
paths must already exist — and appends the inline parameters (ordered by
package path then position) followed by the $refs (ordered by name) to
PathItem.Parameters. Application is exact-path: OAS2 has no path hierarchy,
so /pets/{id} does not inherit /pets path-item parameters, and a target
naming a path with no operations is dropped with a warning. Path-item and
operation parameters co-exist — the operation-level one wins at resolution
(co-presence, not removal). This makes the routes.go "shared parameters -
unsupported for now" note obsolete.
Covered by a programmatic test plus a full-spec golden
(enhancements_shared_parameters_pathitem.json) demonstrating the path-item
array, the $ref, the co-present operation override, and no inheritance on
/pets/{id}.
* contributes go-swagger/go-swagger#2632
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…lict
Build phase (the response side). Responses already register a top-level
`#/responses/{name}` for every swagger:response struct and are referenceable
by name — they were "shared" all along, we just never named it so. Two gaps
remained:
- `swagger:response *` was silently dropped: the `*` failed the scanner's
name regex (the same grammar-migration leftover that P1 fixed for
parameters — the response name was read from EntityDecl.ResponseNames()
rather than the grammar).
- duplicate top-level response names silently overwrote (last-wins).
This commit aligns responses with parameters:
- `swagger:response *` is a synonym for the bare form — a shared response
keyed by the type name. It carries no op-ids (responses have no
status-less injection point) and no /path form. The grammar lexer accepts
`*` (TokenWildcard) → ResponseBlock with no name.
- rxResponseOverride accepts `*` but still rejects a malformed
package-qualified name (so MalformedResponseName keeps flagging it); it is
now a classification gate only.
- EntityDecl.ResponseNames() is removed; responses.Builder.ResponseName()
resolves the name from the grammar (explicit arg, else the Go type name),
mirroring the parameters migration.
- spec.buildResponses orders declarations (package path, then position) and
merges with keep-first conflict handling (new scan.shared-response-conflict
warning), never renaming. An InputSpec overlay response of the same name is
not a conflict — a scanned struct still extends it.
keep-first vs last-wins differ only on a name collision (absent from clean
fixtures), and the grammar-derived name equals the former regex-derived one
for every existing case, so no golden drifts.
* contributes go-swagger/go-swagger#2632
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Build phase: spec.validateSharedRefs runs once the #/parameters and
`#/responses` maps are complete (after path-item parameters are applied) and
walks every path-item and operation parameters list plus each operation's
responses, dropping any reference whose target is not registered:
- a dangling #/parameters/{name} ref → dropped with scan.dangling-parameter-ref
- a dangling #/responses/{name} ref → dropped with scan.dangling-response-ref
A dangling reference is never emitted as an invalid $ref. The main source
is a swagger:operation wholesale-YAML body, whose parameters/responses (and
their $refs) unmarshal verbatim and were previously unvalidated; this pass
also serves as a uniform safety net. Valid refs and non-shared refs (e.g.
`#/definitions/…`) are left untouched.
Tested with fixture 4: opA's resolving refs are kept, opB's dangling refs
are dropped with their warnings.
* contributes go-swagger/go-swagger#2632
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…nder -m
shared-parameters feature (go-swagger#2632). PruneUnusedModels
now also drops shared parameters (#/parameters/*) and shared responses
(#/responses/*) that no operation and no path-item references, not just
unreachable definitions.
The new pruneUnusedSharedObjects runs inside pruneUnusedModels BEFORE the
definition reachability walk: it deletes every unreferenced, non-pinned
shared object (collectSharedRefs is the read-only "is referenced" mirror
of the ref-application passes), each with a located scan.pruned-unused
Hint. Because it precedes the definition walk — whose roots are read from
the same #/parameters and #/responses maps — a definition kept alive only
by a now-pruned shared object becomes prunable in turn.
InputSpec-supplied shared objects are pinned (never pruned), mirroring the
definitions rule, via pinnedParams/pinnedResponses snapshotted at
NewBuilder. Gated by ScanModels like the rest of the prune, so the
"no-op without ScanModels" contract is unchanged.
Provenance: a pruned shared response would otherwise dangle its
/responses/{name}/... anchors (fired inline from the responses builder).
Under PruneUnusedModels those anchors are now buffered (new
ScanCtx.BeginDeferredOrigins/Drop/Flush — a verbatim-flush sibling of the
def-origins window), discarded when the response is pruned, and flushed
after the prune for survivors. The non-prune anchor stream is byte-identical.
Tests: Prune_Off + Prune_On over Fixture 6 (shared-parameters-prune) plus
golden enhancements_shared_parameters_prune.json; provenance non-leak
verified. scanner README §prune documents the new first pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Completes the shared-parameters feature (go-swagger#2632): every shared-parameters fixture now has a captured golden, not just behavioral assertions. F2 (pathitem) and F6 (prune) already had goldens; this adds the remaining four: - enhancements_shared_parameters.json (F1: top-level + refs) - enhancements_shared_parameters_conflict.json (F3: keep-first conflict, independent #/definitions vs #/parameters namespaces) - enhancements_shared_parameters_overrides.json(F5: name override, dedup, dangling-ref drop) - enhancements_shared_parameters_yaml.json (F4: swagger:operation wholesale-YAML ref validation) Each golden is asserted from the existing coverage test that already scans the fixture, so the captured output is pinned alongside its behavioral checks. Generated with UPDATE_GOLDEN=1; full suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Adds a dedicated fixture (shared-parameters-prune-cascade) for the second step of the prune extension: pruning an unreferenced shared response also prunes the definitions reachable ONLY through it, because the shared-object prune runs before the definition reachability walk. Fixture 6 used inline response bodies, so the cascade was correct by construction but had no witness. Here the bodies are named swagger:models: UsedResponse (referenced by listC) -> body Survivor -> Shared UnusedResponse (referenced by nobody) -> body Orphan -> Shared With PruneUnusedModels: UnusedResponse is pruned, and Orphan — reachable only through it — cascades away (a second scan.pruned-unused Hint, from the definition pass). Shared is KEPT: the surviving Survivor still references it, so the prune is reachability-correct, not a naive "drop everything the pruned response touched". PruneCascade_Off is the control (all three models + both responses present), PruneCascade_On the witness, pinned by golden enhancements_shared_parameters_prune_cascade.json. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…ions description/title override feature (go-swagger backlog close-out). Registers two new classifier annotations in the grammar so the scanner accepts them and the parser captures their free-text argument; no builder consumes them yet, so output is unchanged. - grammar: add AnnTitle / AnnDescription kinds (labels, String, AnnotationKindFromName, familyClassifier). - lexer: capture the whole rest-of-line verbatim as the override arg (like swagger:patternProperties); keep a trailing "." for these two kinds since it is sentence content, not punctuation noise — while still classifying the kind from a dot-stripped view so a bare form resolves. - parser: a bare/empty override warns with scan.empty-override (the empty value is still applied downstream as deliberate godoc suppression). - scanner: accept title/description in the field-level classifier set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
consume the override annotations on model schemas and struct fields. An explicit override replaces the godoc-derived title / description; absence leaves the godoc untouched (regression-guarded); a bare swagger:description suppresses the godoc (empty value applied) and raises scan.empty-override. - schema walker: overridesFor() harvests swagger:title / swagger:description from a comment group's sibling classifier blocks; applied after the prose-derived assignment on the model decl and the inline field path. - $ref fields: title and description are symmetric $ref siblings — they ride the same preservation rule (kept under EmitRefSiblings / a forced compound, dropped to a bare $ref under the default flags), threaded through applyToRefField / applyRefSiblingDrop. No title-specific compounding. - empty-override warning is emitted at the builder consumption point, not the parser: sibling classifier blocks are not Walk-ed, so a grammar-stored diagnostic would never reach OnDiagnostic. The grammar treats a bare override as well-formed. - fixture + goldens: enhancements/description-title-override witnesses the model/field overrides, the no-override regression, godoc suppression, the bare-$ref drop, and the EmitRefSiblings sibling preservation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
consume the swagger:description override on response declarations and response headers; reject swagger:title there (OpenAPI 2.0 Response and Header objects have no `title` field) with scan.context-invalid while still applying the description override. - common.Builder gains the shared HarvestOverrides / WarnEmptyOverride / OverrideValue primitive (pure harvest + empty-override warning), now used by both the schema and responses builders; schema's local helper is reduced to a thin wrapper over it (de-duplication). - responses walker: overriddenDescription() applies the description override on the response decl and each header, emits scan.context-invalid for a swagger:title, and scan.empty-override for an empty description. - fixture + golden: enhancements/description-title-override-responses witnesses the overridden response + header descriptions and the title context error. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
multi-line description bodies (Option B) and the fix that lets an override coexist with inline schema keywords on the same field. - lexer: collectDescriptionBody folds the contiguous prose lines following a swagger:description annotation into its argument (blank line / keyword / annotation / EOF terminated), joined with "\n" — so AnnotationArg() returns the whole multi-line description and the folded lines never reach the TITLE/DESC prose surface. swagger:title stays single-line. - grammar family: swagger:title / swagger:description now dispatch through the schema family (like swagger:name) instead of the classifier family, so a co-located validation keyword (maximum:, pattern:, …) on the same field surfaces as a Property and is applied rather than rejected as context-invalid. parseSchemaBlock returns a ClassifierBlock carrying the free-text arg plus harvested body keywords. - fixture + goldens: Widget gains a multi-line `notes` field and a `capacity` field combining a description override with `maximum:` — both witnessed end-to-end; grammar unit tests pin the fold and the keyword coexistence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
close out the override feature. - schema/README.md §user-overrides: new subsection documenting the overrides — precedence, multi-line (Option B), empty-suppression + scan.empty-override, schema-family keyword co-location, and $ref-sibling behaviour. - scanner/README.md: list title/description in the recognised classifier vocabulary, pointing at the schema builder's §user-overrides. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…s (Phase A) Opt-in Options.AfterDeclComments: swagger annotations may live inside a declaration (a struct's leading body comment) or inlined as a trailing comment, so the godoc above the declaration stays clean. Scanner-only — the located comments are folded into the comment source the builders already read, so the grammar and builders are untouched. Phase A (decl-level type carriers, no shared-AST mutation): - struct types: the leading comment groups at the top of the body (before the first field, excluding any field's own Doc) are merged into EntityDecl.Comments (leadingBodyComments). - alias / non-struct types: the trailing TypeSpec.Comment is merged (e.g. `type Count int // swagger:model countType`). - merge builds a fresh CommentGroup (ts.Doc never mutated) so discovery (HasModelAnnotation etc.), naming, validation and the clean-godoc title/ description all flow through the existing pipeline. Idempotent by construction. - routes/operations are already position-agnostic (collect*PathAnnotations scan all file.Comments); the fixture confirms a swagger:route inside a func body is discovered. Option off ⇒ byte-identical (the merge never runs); guarded by the _Off test. Fixture enhancements/after-decl-comments + golden; off/on coverage test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Phase B of AfterDeclComments: fold each struct field's trailing line comment (Field.Comment) into its Field.Doc during indexing, so a field-level annotation can be inlined (`Created string // swagger:strfmt date`) while the field's godoc stays clean. The builders read Field.Doc unchanged. - enrichStructFields(ts) appends Field.Comment onto Field.Doc for each field of a struct type, gated by the new TypeIndex.enrichedFields guard so the shared AST is mutated at most once per field. Runs after afterDeclSource so leadingBodyComments still sees the original field Docs. - positions stay ascending (Doc above < trailing comment) → grammar unchanged. - fixture: Widget gains a `created` field whose strfmt is inlined; the _On test asserts format: date. Off ⇒ inert (the whole model isn't discovered). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…t-enum close-out of AfterDeclComments. - scanner/README.md §after-decl: the two enrichment targets (EntityDecl.Comments vs the Field.Doc mutation), the leading-body-comment rule, idempotency guard, routes/operations already-agnostic, and the out-of-scope notes. - fixture: a `stampType` type-alias case (`type Stamp = string // swagger:model stampType`) confirming Phase A's TypeSpec.Comment path covers inlined aliases. - const-enum (`const X = … // swagger:enum`) is deliberately NOT supported: swagger:enum is type-based (resolves a type, collects its consts), so a lone const has no builder semantics and supporting it would break the scanner-only constraint. Documented in the README and design doc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
The _Off test only asserted two absent definitions; add a golden capturing the FULL inert output so the regression is concretely proven. With the option off the inside-body / inlined annotations contribute nothing: no definitions are emitted, and the only discovery is the location-agnostic route (whose widgetModel response ref is dropped to an empty responses map rather than dangling). The ON↔OFF golden contrast now fully witnesses the feature. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
First phase of the opt-in CleanGoDoc feature.
When a title/description is carried FROM GODOC, godoc-specific doc-link syntax
reads as bracket noise in the emitted spec. Covers the resolution-free
transforms; identifier→schema recomposition in follow-ups.
New internal/builders/godoclink package rewriting links.
- strip doc-link brackets and humanize the leaf identifier via the swag name
mangler ([CustName] -> "cust name", [*inventory.Ledger] -> "ledger");
- drop reference-style link definition lines ([text]: url);
- restore the first identifier of the prose to sentence case;
- conservative recognizer leaves []byte / [0] / [see notes] / bare [id] intact.
Wiring:
- Options.CleanGoDoc (default false) re-exported via codescan.Options;
- a shared mangling.NameMangler + CleanGoDoc()/Mangler() accessors on ScanCtx;
- CleanGoDoc helper on common.Builder (+ a sibling on spec.Builder for the
swagger:meta site), applied at all nine godoc-prose consumption sites
(meta info, route/inline op summary+description, response + header
description, parameter description, model title+description, field
description incl. the $ref-override path).
Applied ONLY to godoc-derived prose: author-written swagger:title /
swagger:description overrides flow through HarvestOverrides and are never
filtered. Off => byte-identical output (existing goldens unchanged).
Tests: godoclink table unit tests; integration TestCoverage_GodocLinks_{Off,On}
with off/on goldens. Suite green, lint clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Adds the marker machinery that bridges the two halves of idiom recomposition
(the load-bearing design piece): which prose is godoc-derived is only known at
the consumption seam, but a referenced schema's final exposed name is only known
after the spec builder reduces definition names. A resolvable doc-link is encoded
here as a marker carrying the schema's fully-qualified definition key; a
post-reduce pass substitutes the final name.
godoclink changes:
- Clean now takes Options{Mangler, Resolver, Self} (was a bare *NameMangler);
Resolution{DefKey, Suffix} and the Resolver callback model identifier→schema
resolution (schemas only); SelfRef models the leading godoc-convention
self-name.
- marker encode + SubstituteMarkers decode, NUL/Unit-Separator delimited (never
occur in Go comments). A marker carries (defKey, exposed field-chain suffix,
humanized fallback, sentence-initial titleize bit). SubstituteMarkers maps
defKey→final name (falling back to the humanized leaf for a pruned/unresolved
key) and titleizes the first identifier; no marker survives the pass.
- leading self-name span handling: with a Resolver + Self, the decl's own
godoc-convention leading name recomposes to its exposed name (titleized);
without a Resolver it is left verbatim.
The live CleanGoDoc path passes a nil Resolver (resolution-free cleanup only), so
output is unchanged and the integration goldens are untouched — the real
go/types resolver and the post-reduce substitution land together in P3, where
markers first reach live output. The marker round-trip (emit→substitute, incl.
pruned-key fallback and collision rename) is unit-tested with a fake resolver.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Completes CleanGoDoc: resolvable doc-links (and a declaration's leading
godoc-convention self-name) are recomposed to the EXPOSED name of the schema
they reference, rather than merely humanized.
Resolver (internal/builders/common/godoc.go):
- godocResolver maps a doc-link reference to (definition key, exposed
field-chain suffix). It reuses ScanCtx.GetModel — so swagger:model overrides
are honored — resolving same-package types and pkg.Type qualifiers via the
enclosing file's imports; a trailing member resolves to its exposed property
name (resolvers.ParseFieldTag + NameFromTags). Non-models (operation funcs,
unknown idents, non-struct field paths) don't resolve, so the leaf is
humanized instead.
- godocSelf supplies the decl's own name + key for leading self-name
recomposition; CleanGoDocSelf wires it on the model title/description site,
CleanGoDoc (resolver, no self) everywhere else.
Substitution (internal/builders/spec/godoc_markers.go):
- substituteGodocMarkers runs right after reduceDefinitionNames(): a
walkSpecProse traversal (mirroring rewriteAllRefs) visits every title /
description / summary and calls godoclink.SubstituteMarkers. finalName maps a
pre-reduce key to renames[key], else the leaf checked against the final
Definitions map, so a pruned/unresolved key collapses to its humanized
fallback. A no-op when CleanGoDoc is off.
Fixture upgraded to exercise the matrix: Widget -> "Gizmo" (swagger:model +
self-name, titleized), [Gadget] -> "Gadget", [Order.CustName] ->
"Order.customer_name" (json field), cross-package [inventory.Ledger] -> "Ledger",
unknown [Sprocket] -> humanized, [the spec]: url dropped, []byte/[0]/[see
notes]/[id] intact. off/on goldens; OFF still byte-identical. Suite green, lint
clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…an-godoc
Maintainer docs for the CleanGoDoc feature (READMEs only; the public doc-site is
tracked separately).
- new internal/builders/godoclink/README.md: the two transforms (cleanup +
recomposition), the consumption-seam vs post-reduce timing split and why it
needs markers, the NUL/Unit-Separator marker format and round-trip contract,
the builder wiring + nine consumption sites, and the deferred follow-ups.
- internal/scanner/README.md §clean-godoc (+ TOC entry): the option-level view
(the scanner holds only the flag + shared NameMangler) cross-referencing the
godoclink README, and the clean-godoc-cluster / godoc-derived-only boundary.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…hod mangler Interface methods have no natural JSON serialization, so codescan invents a property name by running the swag/mangling ToJSONName transform on the Go method name (ID→id, CreatedAt→createdAt). This one-size-fits-all convention is not always what the author wants — an interface already named for its JSON shape, or a codebase with its own canonical-name discipline. Add Options.SkipJSONifyInterfaceMethods (opt-out, default false): when set, methodCarrier emits the Go method name verbatim instead of calling interfaceJSONName. A swagger:name override still wins verbatim regardless — the flag only changes the no-override fallback. Struct-field naming is untouched (it mirrors what encoding/json actually produces). New fixture fixtures/enhancements/interface-no-mangle/ + on/off integration test pin the contract; default-off output is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…lain embeds By default codescan inlines an embedded struct's properties into the embedding schema (mirroring Go field promotion), which loses the "this composes Y" relationship — every embedding struct emits a flat copy of the embedded fields. Downstream client generators that want a reusable base type per embed prefer the allOf composition shape instead. Add Options.DefaultAllOfForEmbeds (opt-in, default false): when set, a plain (non-swagger:allOf-tagged) struct embed with no explicit name is reclassified in scanEmbeddedFields as an allOf member — exactly as if it carried swagger:allOf. It then takes the existing buildAllOf path ($ref when the embed is a model, inline member otherwise) and the embedding struct's own fields move into a sibling allOf member. Scope/precedence (all via the existing allOf path, so stdlib specials and pointer/alias peeling are handled): a json-named embed keeps its nested-property shape (go-swagger#2038); an explicit swagger:allOf already produces this shape; interface embeds are untouched (they compose via allOf regardless). Default-off output is unchanged. New fixture fixtures/enhancements/default-allof-embeds/ + on/off integration test pin the contract (model embed, non-model embed, pointer embed, json-named embed, explicit allOf embed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…ure)
Reframes go-swagger#3211 ("add indentation support"): rather than recover
markdown from ambient godoc (wont-fix — godoc is allergic to markdown), let an
author opt in to a verbatim markdown body via an explicit YAML literal
block-scalar marker on the annotation line:
// swagger:description |
// | col1 | col2 |
// |------|------|
//
// A paragraph after a significant blank line.
`swagger:description |` captures the body verbatim — blank lines, indentation,
table pipes and `---` all preserved — until the next swagger annotation or EOF.
Plain `swagger:description` keeps the blank-terminated Option B behaviour
unchanged; `|` is the opt-in, so output is identical without it.
The capture MUST happen at lex stage 1 (classifyLines): a lone `---` in the
body would otherwise flip the global YAML-fence state and swallow a following
annotation as raw YAML (confirmed by test). A new inLiteralDesc mode emits each
body line as a verbatim tokenRawLine — no fence toggling, no blank-line or
keyword termination — and stage 2's collectDescriptionLiteral folds that run
into the annotation's single raw arg (trailing blanks clipped, marker dropped).
This is the lexer layer + unit tests; the body flows to every swagger:description
consumer through AnnotationArg(). Integration fixture/golden and docs follow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…swagger#3211
Proves the literal block scalar flows from the lexer through to emitted
descriptions: a model and a field carry verbatim markdown (table with leading
pipes, significant blank lines, indented ordered list) into schema.Description.
Also drops the single godoc convention space (`// text`) from each captured
body line — it is comment decoration, not content — so the output matches the
existing Option B description trimming. Author indentation beyond that space,
trailing whitespace (markdown hard breaks), pipes, and blank lines stay
verbatim.
New fixture fixtures/enhancements/inner-markdown/ + integration golden assert
the full path. go-swagger#3211 ("[spec/parsing] add indentation support") is
closed as reframed/by-design: markdown is authored explicitly via
`swagger:description |`, not recovered from ambient godoc.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
grammar/README.md gains §literal-description: the `|` marker, the two-stage capture (stage-1 inLiteralDesc mode so a body `---` can't flip the global YAML fence; stage-2 collectDescriptionLiteral fold), the convention-space strip, and the terminator contract — only a line-leading annotation ends the block, and indentation does not shield a `swagger:`-leading line. Root CLAUDE.md gains a one-line mention beside the annotation conventions. Adds two lexer tests pinning the terminator contract (mid-line swagger: is body; an indented line-leading swagger: still terminates). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Document the shared-parameters feature (go-swagger#2632) landed on this branch, which shipped with fixtures and integration tests but no doc-site coverage. New tutorial (tutorials/sharing-parameters-and-responses.md, weight 25, auto-listed between Routes and Validations): - swagger:parameters * / * <opid> — register fields at #/parameters and $ref them into operations; the standalone `<opid> <name>` marker on a func as the scaling channel. - swagger:parameters /path — inline fields into a path-item (exact path, no hierarchy; co-present with operation-level params). - swagger:response * — register a shared response at #/responses. - The keep-first / dangling-ref / dedup semantics with their six scan.* diagnostic codes. Backed by a new test-covered witness (docs/examples/concepts/sharedparams) mirroring the integration-test ground truth: every JSON pane is a golden a test regenerates (UPDATE_GOLDEN=1 go test ./...). Reference touches (kept light): - annotations.md: a "Shared & path-item targets" note on swagger:parameters and the `*` synonym on swagger:response, both linking the new tutorial. - routes-and-operations.md: forward link to the new tutorial. * contributes go-swagger/go-swagger#2632 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…ides Document the title/description override feature (go-swagger#2632). The annotations let the spec text diverge from a Go doc comment written for Go readers. New how-to (shaping-the-output/overriding-titles-and-descriptions.md, weight 43 — the explicit-override sibling of single-line-comments): - swagger:title / swagger:description on a model and its fields (a property title comes ONLY from an override); un-annotated decls unchanged. - Multi-line swagger:description (Option B) and its blank/keyword/annotation termination. - Keyword co-location (schema-family dispatch keeps a co-located maximum:). - Suppressing a godoc with a bare swagger:description (empty applied + scan.empty-override). - $ref-sibling behaviour (default drop vs EmitRefSiblings keep) as a compare. - Responses & headers: description override applies; swagger:title rejected with parse.context-invalid (OAS2 has no Response/Header title). Backed by a new test-covered witness (docs/examples/shaping/overrides) mirroring the integration-test ground truth; every JSON pane is a golden a test regenerates (UPDATE_GOLDEN=1 go test ./...). The witness reads diagnostics through the public codescan.Diagnostic / codescan.Code surface. Also reflect the shared-parameters prune extension (72971e3): the pruning how-to now states that an unreferenced shared parameter / response is itself pruned under PruneUnusedModels (scan.pruned-unused, InputSpec pinned), before the definition reachability walk. * contributes go-swagger/go-swagger#2632 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Document the AfterDeclComments opt-in (v0.36) (79468be). Motivation: a godoc comment and an API description pursue different goals — the godoc is for Go developers, the API text for spec consumers. Today the swagger:* annotations live in the doc comment above a declaration, mixing the two. AfterDeclComments lets the machinery move inside a struct body or onto a trailing comment so the godoc stays concise and human-facing. New how-to (shaping-the-output/keeping-annotations-out-of-the-godoc.md, weight 41 — beside the godoc/API-text cluster, the placement counterpart of the title/description override page): - swagger:model + decl-level keyword inside a struct body; swagger:strfmt on a field's trailing comment. - annotation inlined on a defined type / type alias trailing comment. - opt-in, default off (off → annotations inert; on → discovered), shown as a compare of the empty vs populated definitions. - v0.36 scope notice (type decls; routes/operations already work in func bodies; const enums a follow-up). Backed by a new test-covered witness (docs/examples/shaping/afterdecl) mirroring the integration-test ground truth: off yields no definitions, on yields widgetModel (+maxProperties, field format), countType, stampType. Every JSON pane is a golden a test regenerates (UPDATE_GOLDEN=1 go test ./...). * contributes go-swagger/go-swagger#2632 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Document the CleanGoDoc opt-in landed on this branch (v0.36), which shipped with a fixture and integration test but no doc-site coverage (ff5733c). Motivation: a Go doc comment can use godoc doc-link syntax ([Gadget], [Order.CustName], reference-style [text]: url lines) that renders on pkg.go.dev but reads as bracket noise when carried into a spec description — and the bracketed Go identifier is rarely the name the schema is exposed under. CleanGoDoc strips the brackets and recomposes resolvable links to the exposed name, so the prose tracks the generated definitions. New how-to (shaping-the-output/cleaning-godoc-doc-links.md, weight 45, in the godoc/API-text cluster): - doc-links recompose to the exposed name ([Gadget] -> Gadget, [Order.CustName] -> Order.customer_name, self-name Widget -> Gizmo via swagger:model gizmo, cross-package [inventory.Ledger] -> Ledger); - unresolved links humanized ([Sprocket] -> sprocket); - reference-definition lines dropped; - conservative recognizer leaves ordinary brackets ([0], [see notes], [id]); - recomposition runs after name resolution, so collision renames are reflected; godoc-derived prose only (overrides never touched); opt-in, default off (byte-identical). Backed by a new test-covered witness (docs/examples/shaping/godoclinks + inventory subpackage) mirroring the integration-test ground truth; off vs on shown as a compare. Note: gofmt moves a link-reference-definition to the end of a doc comment, past swagger:model — so the ref-def-dropping case is witnessed on a field (no annotation to truncate the description), not the model doc comment. * contributes go-swagger/go-swagger#2632 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
The "Shaping the output" how-to section had grown to 18 flat pages with a single long left-menu list. Group them into five weighted subsections, each a card-listing _index.md so the Relearn sidebar shows a collapsible hierarchy: - Scope & discovery (what gets scanned / which types are emitted) - Names & $refs (definition names, alias & $ref rendering) - Titles & descriptions (the human-readable text) - Field types & formats (per-property rendering) - Response bodies (payloads without a swagger:response struct) The 18 pages are git-moved into the subsections and re-weighted within each. The ~38 cross-references that pointed at the old flat paths are rewritten to move-proof filename-only relrefs (basenames are unique site-wide), so future moves don't break links. Verified by a clean Hugo build (no unresolved refs) and rendered-HTML spot checks that the converted links resolve to the new URLs. Add a new Options reference (maintainers/options.md), alongside the Annotations and Keyword references: every field of codescan.Options — its type, default, and effect — transcribed faithfully from the struct godoc, grouped by concern and cross-linked to the how-to that shows it in action. The maintainers landing page now lists it as a third reference card. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…aceMethods Two new opt-in Options knobs landed, both shaping the "Names & $refs" surface. Document each as a test-backed how-to in the shaping-the-output/names-and-refs/ subsection, and add a row for each to the Options reference. DefaultAllOfForEmbeds — render a plain (untagged, unnamed) struct embed as an allOf composition instead of inlining its promoted properties: a $ref member when the embedded type is a model, an inline member otherwise, with the embedding struct's own fields in a sibling member. json-named embeds (#2038), swagger:allOf embeds, and interface embeds are unaffected. New how-to composing-embeds-with-allof.md (weight 35) with an off-vs-on compare; witness docs/examples/shaping/embedallof (model + non-model + pointer + json-named + tagged embeds). SkipJSONifyInterfaceMethods — emit interface-method property names verbatim (ID, CreatedAt) instead of the auto-jsonified spelling (id, createdAt). Only interface methods are affected; struct fields and swagger:name overrides are untouched. New how-to interface-method-names.md (weight 25) with an off-vs-on compare; witness docs/examples/shaping/interfacenames. Both witnesses mirror the upstream integration tests (interface-no-mangle, default-allof-embeds) and regenerate via UPDATE_GOLDEN=1. Verified: examples suite no drift, golangci-lint 0 issues, markdown lint+links clean, Hugo 77 pages 0 warn/err. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
A new annotation form landed (go-swagger#3211): ending a swagger:description line with a lone YAML literal block-scalar marker `|` captures the body verbatim — blank lines, indentation, table pipes and `---` all preserved — until the next line-leading annotation or end of comment. Plain swagger:description keeps the blank-line-terminated Option B behaviour, so the `|` is opt-in and output is identical without it. New how-to titles-and-descriptions/markdown-descriptions.md (weight 15, beside overriding-titles-and-descriptions): a plain-vs-verbatim compare showing Option B dropping a markdown table at the first blank line while the `|` form carries the whole table + bullet list through, plus the field-description case, the title-still-from-preamble note, and the terminator contract (a mid-line `swagger:` is prose; an indented line-leading `swagger:` still terminates). Added a forward link from the overriding-titles page's "Multi-line descriptions" section. This is annotation syntax, not an Options knob, so there is no Options-reference row. Witness docs/examples/shaping/markdowndesc (Plain model folded by Option B vs Markdown model + field captured verbatim) mirrors the upstream integration test (inner-markdown) and regenerates via UPDATE_GOLDEN=1. Verified: examples suite no drift, golangci-lint 0 issues, markdown lint+links clean, Hugo 78 pages 0 warn/err. * contributes go-swagger/go-swagger#3211 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
The "Putting it together" capstone showed its generated Swagger 2.0 document as JSON only. Add a "Seeing it rendered" section that feeds the same golden spec to the Relearn `openapi` shortcode (Swagger UI), closing the loop the capstone is about: annotated Go → the JSON → the API docs those annotations produce. The widget reads the existing test-covered golden as a Hugo asset (examples/basic/testdata/swagger.json, already mounted), so the live view is driven by the same UPDATE_GOLDEN-regenerated file as the JSON block and can't drift from it. Swagger UI is bundled in the theme (no CDN), so the build stays offline-clean, and the heavy JS loads only on this one page. The widget is rendered inline (always visible) rather than inside a tab: Relearn hides inactive tab panels with `display:none`, and Swagger UI renders into an iframe that needs a laid-out (visible) ancestor — inside a hidden tab it paints at zero height and `switchTab` re-inits Mermaid but not openapi, so it never recovers. A tabbed presentation is feasible with a small re-render shim and is tracked separately. First item from the doc-site wishlist (W1). Verified: Hugo 78 pages 0 warn/err, the openapi container + inlined spec render, swagger-ui-bundle.js is emitted locally, markdown lint+links clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Pilot for the forward-looking tabbed-example pattern:
a two-card example where the left card is the annotated Go (always visible)
and the right card is tabbed — "Spec" (the curated JSON
fragment, default) and "SwaggerUI" (the whole spec rendered live by Swagger UI).
Applied to the `swagger:route` pane of the Routes & operations tutorial.
Pieces:
- layouts/shortcodes/examplelive.html — the two-card + tabbed-right shortcode;
the SwaggerUI tab feeds a whole-spec golden through the theme's openapi
shortcode.
- custom-header.html — the right-card tab CSS + a small script that lazily
(re)renders the openapi widget when the SwaggerUI tab is first revealed.
Swagger UI cannot paint inside a display:none tab panel, so we let the theme
re-render it by firing the `afterprint` event it already handles (a pilot
shortcut; a dedicated re-render entrypoint is the follow-up).
- concepts/routes witness now also emits `full.json`, the whole-spec golden the
SwaggerUI tab renders (the per-pane goldens are focused fragments of it) —
decision B: the live view is the real, test-covered scanner output and can't
drift.
Verified: examples suite no drift, Hugo 78 pages 0 warn/err, markdown links
clean, and the rendered widget paints the live API (reviewed on localhost).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Fold the tabbed-example pilot into the existing `example` shortcode and make it
multi-widget safe, so any tutorial pane can opt into a live SwaggerUI tab.
- `example` gains an optional `full=` (a whole-spec golden). Without it the
shortcode renders exactly as before (left Go / right JSON); with it the right
pane becomes a tabbed card — "Spec" (the fragment, default) and "SwaggerUI"
(the whole spec rendered live). The standalone `examplelive` shortcode is
removed (subsumed).
- The render no longer borrows the theme's openapi widget (which uses one fixed
iframe id, so only one per page could work). Each live pane now emits its own
`.el-openapi` container with a UNIQUE id, loads the spec by URL, and renders
into its own CSS-isolated iframe on first reveal — multiple live examples
coexist on a page. Swagger UI assets load because the shortcode sets the
page's `hasOpenApi` store flag; the iframe links the same three theme
stylesheets the native widget does (swagger-ui + swagger + format-html) so it
matches the site theme.
The Routes & operations tutorial now drives two independent live examples (the
`route` and `operation` panes) off the shared `full.json` whole-spec golden.
Verified: examples suite green, Hugo 78 pages 0 warn/err, two distinct container
ids, markdown links clean, both widgets render independently and on-theme
(reviewed on localhost).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
…rials
Add the right-card "SwaggerUI" tab (the `example` shortcode's `full=` opt-in,
landed in previous commit) to one representative pane of each route-bearing tutorial, so a
reader can flip from the focused JSON fragment to the whole spec rendered live:
- security — secured operations + api_key/oauth2 schemes
- other-type-decorators — the readOnly model + the deprecated operation
- validations — the validated model (min/max, pattern, format render
in Swagger UI's schema view)
- examples-and-defaults — models carrying example values
Each tutorial's witness now also emits a `full.json` whole-spec golden (decision
B: the live view is the real, test-covered scanner output and can't drift); the
focused per-pane goldens remain slices of it. Every live container gets a unique
id, so the widgets coexist on a page and across pages.
Not done deliberately: the sharedparams tutorial uses code/compare panes (not
`example`), and the pure model tutorials (model-definitions, polymorphic, maps)
are model-only — Swagger UI would show a "no operations" banner — so they are
left for a follow-up if wanted.
Verified: examples suite no drift, Hugo 78 pages 0 warn/err, markdown links
clean, all four render live (reviewed on localhost).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #55 +/- ##
==========================================
- Coverage 81.85% 81.55% -0.31%
==========================================
Files 80 84 +4
Lines 7594 8522 +928
==========================================
+ Hits 6216 6950 +734
- Misses 1015 1149 +134
- Partials 363 423 +60 ☔ View full report in Codecov by Harness. |
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