Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
637e2c4
feat: derive field names from configurable struct tags (NameFromTags)
fredbi Jun 23, 2026
b179dcc
feat: response-level examples by mime on struct swagger:response
fredbi Jun 23, 2026
d15be5c
docs: doc-site coverage for NameFromTags and response examples by mime
fredbi Jun 23, 2026
8ae5132
feat(shared-parameters): grammar-owned targeting parse + scanner ref …
fredbi Jun 24, 2026
66ce6a5
feat(shared-parameters): register top-level #/parameters with keep-fi…
fredbi Jun 24, 2026
63ef439
feat(shared-parameters): wire shared parameters into operations as $refs
fredbi Jun 24, 2026
75921b1
feat(shared-parameters): apply path-item parameters from swagger:para…
fredbi Jun 24, 2026
b1efba3
feat(shared-parameters): swagger:response * synonym + keep-first conf…
fredbi Jun 24, 2026
cd2966c
feat(shared-parameters): validate shared-namespace refs, drop danglers
fredbi Jun 24, 2026
c151bab
feat(shared-parameters): prune unreferenced shared params/responses u…
fredbi Jun 25, 2026
6858a3c
test(shared-parameters): golden coverage for fixtures 1/3/4/5 (P8)
fredbi Jun 25, 2026
60e18f6
test(shared-parameters): witness the prune cascade
fredbi Jun 25, 2026
995b740
feat(overrides): register swagger:title / swagger:description annotat…
fredbi Jun 25, 2026
8e29a53
feat(overrides): apply swagger:title / swagger:description on schemas
fredbi Jun 25, 2026
27f3012
feat(overrides): apply swagger:description on responses & headers
fredbi Jun 25, 2026
5bef5b6
feat(overrides): multi-line swagger:description + keyword co-location
fredbi Jun 25, 2026
02a6681
docs(overrides): document swagger:title / swagger:description overrides
fredbi Jun 25, 2026
a989c8c
feat(scanner): AfterDeclComments — annotations inside/below type decl…
fredbi Jun 25, 2026
fbc47b6
feat(scanner): AfterDeclComments — field trailing comments (Phase B)
fredbi Jun 25, 2026
52d89a0
docs(scanner): document AfterDeclComments; alias coverage; defer cons…
fredbi Jun 25, 2026
e21b49f
test(scanner): golden-pin the AfterDeclComments OFF case
fredbi Jun 25, 2026
e98a4eb
feat(scanner): CleanGoDoc — godoc-syntax filtering (strip/humanize)
fredbi Jun 25, 2026
3d91dd5
feat(scanner): CleanGoDoc — marker contract for idiom recomposition
fredbi Jun 25, 2026
040dbea
feat(scanner): CleanGoDoc — idiom recomposition resolver + substitution
fredbi Jun 25, 2026
ba923ae
docs(builders): document CleanGoDoc — godoclink README + scanner §cle…
fredbi Jun 25, 2026
bf5c230
feat(scanner): SkipJSONifyInterfaceMethods — opt out of interface-met…
fredbi Jun 26, 2026
86c6464
feat(scanner): DefaultAllOfForEmbeds — opt-in allOf composition for p…
fredbi Jun 26, 2026
bedc8d8
feat(grammar): swagger:description | literal block scalar (lexer capt…
fredbi Jun 26, 2026
86858fd
feat(scanner): swagger:description | end-to-end + fixture; closes go-…
fredbi Jun 26, 2026
c561198
docs(grammar): document swagger:description | literal block
fredbi Jun 26, 2026
dc05fb6
docs: doc-site coverage for shared parameters & responses
fredbi Jun 25, 2026
e7e9741
docs: doc-site coverage for swagger:title / swagger:description overr…
fredbi Jun 25, 2026
d5495a4
docs: doc-site coverage for AfterDeclComments
fredbi Jun 25, 2026
7aba6ad
docs: doc-site coverage for CleanGoDoc (godoc doc-links)
fredbi Jun 25, 2026
c8fea7a
docs: subsection the "Shaping the output" menu + add Options reference
fredbi Jun 26, 2026
fb38ec4
docs: doc-site coverage for DefaultAllOfForEmbeds + SkipJSONifyInterf…
fredbi Jun 26, 2026
1e3ae92
docs: doc-site coverage for swagger:description | (verbatim markdown)
fredbi Jun 26, 2026
f0c7225
docs(doc-site): render the capstone spec live with Swagger UI (W1)
fredbi Jun 26, 2026
77fb493
docs(doc-site): tabbed-example pilot — live SwaggerUI on a tutorial pane
fredbi Jun 26, 2026
fd1b5f1
docs(doc-site): generalize the live-spec tab into `example`
fredbi Jun 26, 2026
99c0cf4
docs(doc-site): roll out the live SwaggerUI tab to route-bearing tuto…
fredbi Jun 26, 2026
cb595c1
chore: relint
fredbi Jun 26, 2026
f5009e7
doc: reformatted go comments
fredbi Jun 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
21 changes: 21 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,24 @@ malformed input, the petstore, aliased schemas, go123-specific forms, and cross-
- `SkipAllOfCompounding` — never emit an `allOf` compound; validations/externalDocs
dropped (description/extensions too, unless `EmitRefSiblings` keeps them as
siblings), each with a diagnostic. For consumers (e.g. go-swagger) wanting bare refs.
- `DefaultAllOfForEmbeds` — opt-in (default false): render a plain
(non-`swagger:allOf`) struct embed as allOf composition instead of inlining
its properties — a `$ref` allOf member for a model embed, an inline member
otherwise, with the embedding struct's own fields in a sibling member.
Json-named embeds (go-swagger#2038) and interface embeds are unaffected;
`swagger:allOf` already wins. See `internal/builders/schema/README.md#allof`.
- `SetXNullableForPointers` — emit `x-nullable: true` on pointer fields.
- `NameFromTags` — ordered list of struct-tag types a field's emitted name is
derived from (schema properties, parameters, response headers). First listed
tag that supplies a usable name wins. nil/unset ⇒ `["json"]` (historic);
explicit empty slice ⇒ Go field name. Only the name; encoding/json directives
(`-`, `,omitempty`, `,string`) always come from the `json` tag. e.g.
`["form","json"]` for gin (go-swagger#2912/#1391).
- `SkipJSONifyInterfaceMethods` — opt out (default false) of the auto-jsonify
mangler on interface-method property names (`ID`→`id`, `CreatedAt`→`createdAt`).
When true the Go method name is emitted verbatim; `swagger:name` still wins
verbatim regardless. Does not affect struct fields. See
`internal/builders/schema/README.md#interface-naming`.
- `SkipExtensions` — suppress `x-go-*` vendor extensions.
- `OnDiagnostic` — callback sink for all scan-time observations (the only output
channel; codescan never writes to stdout/stderr).
Expand All @@ -148,6 +165,10 @@ malformed input, the petstore, aliased schemas, go123-specific forms, and cross-
- Uses `golang.org/x/tools/go/packages` for module-aware package loading.
- Comment annotations follow the go-swagger convention (`swagger:route`, `swagger:operation`,
`swagger:parameters`, `swagger:response`, `swagger:model`, etc.).
- `swagger:description |` (YAML literal block-scalar marker) captures a verbatim
markdown body — blank lines, indentation, table pipes preserved — until the next
line-leading annotation or EOF; reframes go-swagger#3211. Plain `swagger:description`
stays blank-terminated. See `internal/parsers/grammar/README.md#literal-description`.
- The scanner works at the AST / `go/types` level — it never executes or compiles scanned code.
- Parsers never import builders; they write through the interfaces in `internal/ifaces`.
When adding a new annotation, extend the relevant builder's `taggers.go` rather than reaching
Expand Down
2 changes: 1 addition & 1 deletion docs/doc-site/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ your own program (see [Getting started]({{% relref "/getting-started" %}})).
When document-level metadata (info, security, servers) is more naturally
hand-authored, you do not have to push it into the code: scan the code for the
operations and models, and **overlay** the result onto a hand-written base
document (see [Shaping the output → Overlaying a spec]({{% relref "/shaping-the-output/overlaying-a-spec" %}})).
document (see [Shaping the output → Overlaying a spec]({{% relref "overlaying-a-spec" %}})).

## A community toolkit

Expand Down
2 changes: 1 addition & 1 deletion docs/doc-site/annotation-index/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ tutorial that shows the annotation as runnable Go next to the spec it produces;
| `swagger:strfmt` | type declaration | `{type: string, format: …}` at every use | [example]({{% relref "/tutorials/model-definitions#swaggerstrfmt" %}}) | [reference]({{% relref "/maintainers/annotations#swaggerstrfmt" %}}) |
| `swagger:enum` | named type | an `enum` array (+ `x-go-enum-desc`) | [example]({{% relref "/tutorials/model-definitions#swaggerenum" %}}) | [reference]({{% relref "/maintainers/annotations#swaggerenum" %}}) |
| `swagger:allOf` | embedded field / struct | an `allOf` composition | [example]({{% relref "/tutorials/model-definitions#swaggerallof" %}}) | [reference]({{% relref "/maintainers/annotations#swaggerallof" %}}) |
| `swagger:alias` *(deprecated)* | type alias | **no effect** — alias rendering is controlled by Go aliases + options | [how-to]({{% relref "/shaping-the-output/alias-rendering" %}}) | [reference]({{% relref "/maintainers/annotations#swaggeralias--deprecated" %}}) |
| `swagger:alias` *(deprecated)* | type alias | **no effect** — alias rendering is controlled by Go aliases + options | [how-to]({{% relref "alias-rendering" %}}) | [reference]({{% relref "/maintainers/annotations#swaggeralias--deprecated" %}}) |
| `swagger:route` | func / var doc | a `paths` entry + operation | [example]({{% relref "/tutorials/routes-and-operations#swaggerroute" %}}) | [reference]({{% relref "/maintainers/annotations#swaggerroute" %}}) |
| `swagger:operation` | func / var doc | a `paths` entry (YAML body) | [example]({{% relref "/tutorials/routes-and-operations#swaggeroperation" %}}) | [reference]({{% relref "/maintainers/annotations#swaggeroperation" %}}) |
| `swagger:parameters` | struct declaration | parameters on the named operation(s) | [example]({{% relref "/tutorials/routes-and-operations#swaggerparameters" %}}) | [reference]({{% relref "/maintainers/annotations#swaggerparameters" %}}) |
Expand Down
8 changes: 4 additions & 4 deletions docs/doc-site/getting-started/usage-as-a-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ an existing spec via `Options.InputSpec`.
| `InputSpec` | Overlay: merge discoveries on top of an existing spec. |
| `BuildTags`, `Include`/`Exclude` | Scope control over what gets scanned. |
| `RefAliases`, `TransparentAliases` | Alias-handling knobs. |
| `EmitRefSiblings` | Emit a `$ref`'d field's description and extensions as direct `$ref` siblings instead of an `allOf` wrap — see [Descriptions beside a $ref]({{% relref "/shaping-the-output/descriptions-beside-a-ref" %}}). |
| `SkipAllOfCompounding` | Never wrap a `$ref`'d field in an `allOf`; emit a bare `$ref` and drop the decorations that need a compound — see [Descriptions beside a $ref]({{% relref "/shaping-the-output/descriptions-beside-a-ref" %}}). |
| `EmitRefSiblings` | Emit a `$ref`'d field's description and extensions as direct `$ref` siblings instead of an `allOf` wrap — see [Descriptions beside a $ref]({{% relref "descriptions-beside-a-ref" %}}). |
| `SkipAllOfCompounding` | Never wrap a `$ref`'d field in an `allOf`; emit a bare `$ref` and drop the decorations that need a compound — see [Descriptions beside a $ref]({{% relref "descriptions-beside-a-ref" %}}). |
| `DescWithRef` | _Deprecated_ — preserve a description-only `$ref` field via a single-arm `allOf`; prefer `EmitRefSiblings`. |
| `SkipExtensions` | Suppress `x-go-*` vendor extensions. |
| `SkipEnumDescriptions` | Keep the `swagger:enum` const→value mapping out of property/parameter descriptions (it still rides `x-go-enum-desc`). |
| `EmitXGoType` | Stamp `x-go-type` (the fully-qualified Go type) on every definition — see [Vendor extensions]({{% relref "/shaping-the-output/vendor-extensions#stamping-x-go-type" %}}). |
| `SingleLineCommentAsDescription` | Route single-line comments to `description` instead of `title`/`summary` — see [Single-line comments]({{% relref "/shaping-the-output/single-line-comments" %}}). |
| `EmitXGoType` | Stamp `x-go-type` (the fully-qualified Go type) on every definition — see [Vendor extensions]({{% relref "vendor-extensions#stamping-x-go-type" %}}). |
| `SingleLineCommentAsDescription` | Route single-line comments to `description` instead of `title`/`summary` — see [Single-line comments]({{% relref "single-line-comments" %}}). |

See the [godoc][godoc] for the full list.

Expand Down
12 changes: 8 additions & 4 deletions docs/doc-site/maintainers/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ description: |
---

This section is the **reference compendium**: the precise, exhaustive
description of the language codescan parses. It is written for people who want
the full contract — annotation authors looking up an exact rule, and
contributors porting, extending, or debugging the parser.
description of the language codescan parses and the options that drive it. It is
written for people who want the full contract — annotation authors looking up an
exact rule, library callers looking up an option, and contributors porting,
extending, or debugging the parser.

If you are learning codescan by example, start with the
[Tutorials]({{% relref "/tutorials" %}}) instead — they show the same concepts
as runnable Go with the spec they produce, side by side. The
[Annotation index]({{% relref "/annotation-index" %}}) cross-references every
annotation to both its tutorial and its entry here.

## The four documents
## The reference documents

{{< children type="card" description="true" >}}

Expand All @@ -28,6 +29,9 @@ annotation to both its tutorial and its entry here.
- **[Keywords]({{% relref "keywords" %}})** — the per-keyword reference card:
every `keyword: value` form, its value shape, and the contexts where it is
legal.
- **[Options]({{% relref "options" %}})** — every field of `codescan.Options`:
its type, default, and effect, cross-linked to the how-to that shows it in
action. The library-caller reference.
- **[Sub-languages]({{% relref "sub-languages" %}})** — the smaller languages
embedded inside annotation bodies (`Parameters:` / `Responses:` grammars,
YAML surfaces, prose classification).
Expand Down
23 changes: 21 additions & 2 deletions docs/doc-site/maintainers/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ By default the const→value mapping is folded into the property's
`description` (as above) **and** duplicated in `x-go-enum-desc`. Set the
scanner option `SkipEnumDescriptions: true` to keep the authored prose as
the description; the mapping then rides `x-go-enum-desc` only. See
[Vendor extensions]({{% relref "/shaping-the-output/vendor-extensions" %}}).
[Vendor extensions]({{% relref "vendor-extensions" %}}).

**Legal keywords.** Schema-context keywords. The `enum:` keyword can
ALSO be used inline on the type doc to force a value set; when present,
Expand Down Expand Up @@ -682,6 +682,22 @@ packages** and matched to operations by operation ID — so a shared
parameter set can live in its own package, as long as that package is in
the scan set.

**Shared & path-item targets.** The first argument need not be an
operation ID. A `*` wildcard or a `/path` switches the annotation to the
spec-level **shared namespace**:

- `swagger:parameters *` registers the struct's fields at the spec top
level (`#/parameters/{name}`) for reuse; `swagger:parameters * <opid>…`
also `$ref`s them into the listed operations.
- `swagger:parameters /path` inlines the fields into that **exact**
path-item (OAS2 has no path hierarchy).
- A standalone `swagger:parameters <opid> <name>…` (or `/path <name>…`)
marker on a **function** `$ref`s an already-registered shared parameter
into that operation / path-item.

See [Sharing parameters & responses]({{% relref "/tutorials/sharing-parameters-and-responses" %}})
for the walkthrough and the keep-first / dangling-ref diagnostics.

**Sample.**

```go
Expand Down Expand Up @@ -755,7 +771,10 @@ intentional, not a missing type.
**Where it goes.** On a struct declaration.

**Argument shape.** Optional IDENT — the published response name.
Default: the Go type's name.
Default: the Go type's name. A `*` wildcard (`swagger:response *`) is a
synonym for the bare form that explicitly marks the response as a
**shared** one, registered at `#/responses/{name}` for operations to
`$ref` by name — see [Sharing parameters & responses]({{% relref "/tutorials/sharing-parameters-and-responses" %}}).

**Sample.**

Expand Down
33 changes: 31 additions & 2 deletions docs/doc-site/maintainers/keywords.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ formal productions should read [grammar.md]({{% relref "grammar" %}}).
- [Schema decorators](#schema-decorators) — `default`, `example`, `enum`, `required`, `readOnly`, `discriminator`, `deprecated`
- [Parameter location](#parameter-location) — `in`
- [Meta single-line keywords](#meta-single-line-keywords) — `schemes`, `version`, `host`, `basePath`, `license`, `contact`
- [Body keywords](#body-keywords) — `consumes`, `produces`, `security`, `securityDefinitions`, `responses`, `parameters`, `extensions`, `infoExtensions`, `tos`, `externalDocs`, `tags`
- [Body keywords](#body-keywords) — `consumes`, `produces`, `security`, `securityDefinitions`, `responses`, `parameters`, `examples`, `extensions`, `infoExtensions`, `tos`, `externalDocs`, `tags`

---

Expand Down Expand Up @@ -141,6 +141,7 @@ them. Detailed entries follow this table.
| `securityDefinitions` | `security definitions`, `security-definitions` | raw-block (YAML map) | meta |
| `responses` | — | raw-block (response sub-language) | route, operation |
| `parameters` | — | raw-block (parameter chunk sub-language) | route, operation |
| `examples` | — | raw-block (YAML map keyed by mime type) | response |
| `extensions` | — | raw-block (YAML map of `x-*` entries) | meta, route, operation, schema, param, header |
| `infoExtensions` | `info extensions`, `info-extensions` | raw-block (YAML map of `x-*` entries) | meta |
| `tos` | `terms of service`, `terms-of-service`, `termsOfService` | raw-block (prose paragraph) | meta |
Expand Down Expand Up @@ -416,7 +417,9 @@ type PageParam int

An example value for the schema, surfaced in tooling. Same raw-value
shape as `default`. Maps to `schema.example` (or `parameter.example`
for SimpleSchema parameters).
for SimpleSchema parameters). This is the **singular**, schema-scoped
keyword; for the **plural** response-scoped [`examples`](#examples) (a
map keyed by mime type) see the Body keywords section.

### `enum`

Expand Down Expand Up @@ -710,6 +713,32 @@ Responses:
default: response:genericError
```

### `examples`

Response-level examples on a `swagger:response` struct — a YAML map
whose first-level keys are **mime types** and whose values are the
example payloads, populating the OAS2 `Response.examples` field. Note
the OAS2 keyword split: the **plural** `examples` is the *response*
keyword (this one); the **singular** [`example`](#example) is the
schema / param / header / items decorator. The `swagger:operation` YAML
body carries `examples` natively (it is unmarshalled straight into the
spec types); this keyword is the struct-`swagger:response` counterpart.

```go
// swagger:response widgetResponse
//
// examples:
//
// application/json:
// name: alice
// count: 3
// application/xml: "<widget><name>alice</name></widget>"
type WidgetResponse struct {
// in: body
Body Widget `json:"body"`
}
```

### `parameters`

Per-route / per-operation parameter declarations. Body is a sequence
Expand Down
Loading
Loading