Skip to content

docs(CLI): generate CLI v2 code samples from the spec#1218

Open
jablan wants to merge 9 commits into
mainfrom
feat/generate-cli-examples
Open

docs(CLI): generate CLI v2 code samples from the spec#1218
jablan wants to merge 9 commits into
mainfrom
feat/generate-cli-examples

Conversation

@jablan

@jablan jablan commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

What

Auto-generate the CLI v2 x-code-samples for every endpoint instead of maintaining them by hand.

A handlebars supporting-file template (cli_examples.handlebars) emits examples/cli.yaml (keyed by operationId), and scripts/inject-cli-examples.js appends each operation's CLI sample into the compiled bundle (doc/compiled.json, tmp/compiled.yaml) after bundling.

How it works

  • Each path file carries x-cli-command: <noun> <subcommand> (the command string the template can't derive, since handlebars here lacks snake_case/split helpers) and its existing inline Curl sample. No CLI sample / no $ref in source files.
  • make bundle: bundle YAML → make examples (regenerates examples/cli.yaml) → bundle JSON+YAML → inject CLI samples into both.
  • A missing example is a no-op, so adding a new endpoint never breaks bundle/validate. Running make (or make bundle) regenerates and injects it.

Why docs: not feat:

The CLI's behavior is unchanged — only how its example docs are generated. No client version bump / binary release intended.

Notable

  • Generated examples reflect the real CLI (correct command names like webhook_deliveries/versions_history, complete flag coverage) and fix numerous stale/incorrect hand-written samples — hence the large path-file diff.
  • Two spec example bugs fixed along the way (also affected the Curl samples):
    • distributions format_options: malformed JSON example → proper object
    • styleguides grammar_consistency: empty example → real example
  • All 116 --data JSON payloads validate.
  • Generator/template gotchas documented in openapi-generator/templates/TEMPLATING.md.

Known limitation

The 2 multipart endpoints (uploads/create, screenshots/create) show synthetic placeholder values for form fields (e.g. --name "name_example") — the go generator drops multipart form-field examples. Command structure and flags are correct.

🤖 Generated with Claude Code

jablan and others added 4 commits June 26, 2026 13:50
Auto-generate the `CLI v2` x-code-samples for every endpoint instead of
maintaining them by hand. A new handlebars supporting-file template
(cli_examples.handlebars) emits examples/cli.yaml during `make cli`, and each
path file references its example via a $ref into that file, which the bundler
inlines into doc/compiled.json.

- Add cli_examples.handlebars + files: wiring in cli_lang.yaml
- Add x-cli-command to every path file (the noun+subcommand the template
  cannot derive, since handlebars lacks snake_case/split helpers)
- Replace inline CLI v2 samples with $ref to examples/cli.yaml
- Fix spec example bugs surfaced along the way:
  - distributions format_options: malformed JSON example -> proper object
  - styleguides grammar_consistency: empty example (also broke the Curl
    sample) -> real example
- Document generator/template gotchas in templates/TEMPLATING.md

The generated examples reflect the real CLI (correct command names, complete
flag coverage) and fix numerous stale/incorrect hand-written samples.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Path files no longer carry a CLI v2 x-code-sample or a $ref to one. Instead,
scripts/inject-cli-examples.js appends each operation's generated sample (from
examples/cli.yaml, matched on operationId) into the compiled bundle after
swagger-cli runs.

This removes the dangling-$ref failure mode: adding an endpoint no longer
breaks bundle/validate when its example doesn't exist yet (a missing example is
a no-op). `make bundle` now regenerates examples/cli.yaml (via a dedicated
examples target) and injects into doc/compiled.json + tmp/compiled.yaml.

- Add scripts/inject-cli-examples.js
- Add openapi-generator/cli_examples_lang.yaml (examples-only generate)
- Add `examples` Makefile target; wire regen+inject into `bundle`
- Key examples/cli.yaml by operationIdOriginal (matches compiled operationId)
- Remove CLI $ref lines from path files (keep inline Curl + x-cli-command)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mples

# Conflicts:
#	doc/compiled.json
#	paths/key_links/create.yaml
@github-actions

Copy link
Copy Markdown
Contributor

API changelog (oasdiff)

Doc-only edits (descriptions, examples) do not appear here.

No changes to report, but the specs are different.
Run 'oasdiff diff' to see structural differences.

jablan and others added 5 commits June 26, 2026 14:44
`make bundle` previously ran `make examples` (openapi-generator + Java), which
broke the Node-only `lint` and `compare-output` CI jobs. Bundle now only injects
the committed examples/cli.yaml (Node only); examples regeneration moves to the
`cli` target (where Java is available) plus a standalone `make examples`.

compare-output now runs scripts/inject-cli-examples.js after bundling so it
reproduces the committed doc/compiled.json.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Array-typed flags (e.g. --locale_ids, --filters, --states) were rendered as a
quoted JSON string containing quotes (--locale_ids "["de","en"]"), which is
invalid. The flag-rendering branch only handled isMap/isBoolean; isArray and
isNumeric fell through to string quoting.

Arrays now render as single-quoted JSON ('["de","en"]', matching how the CLI
parses []string flags via json.Unmarshal) and numerics render unquoted, aligning
the flag path with the --data body path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Header params (--if_modified_since, --if_none_match) were rendered from baseName
(If-Modified-Since), but the CLI exposes them as ToSnakeCase(exportName). Flag
names (and placeholders) now use lower+dash->underscore, matching the real CLI;
all other params already had snake_case baseNames so are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two issues prevented `make examples` from regenerating examples/cli.yaml:
- The target name collided with the examples/ directory, so make considered it
  up to date and did nothing. Added a .PHONY declaration for all targets.
- Use `npx openapi-generator-cli` (like the swagger-cli calls) so it resolves to
  the pinned npm dependency instead of an unconfigured asdf shim.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add example values to the conditional-request header params so their CLI
samples render real values instead of synthetic placeholders.

The If-None-Match ETag example contains double quotes (W/"123456789"), which
surfaced a gap: the flag-path string rendering did not escape inner quotes
(only the --data body path did). Escape them there too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant