Skip to content

gen-docs: document options of commands that have subcommands - #1231

Open
Duncanma wants to merge 1 commit into
mainfrom
fix-gen-docs-nonleaf-options
Open

Duncanma wants to merge 1 commit into
mainfrom
fix-gen-docs-nonleaf-options

Conversation

@Duncanma

@Duncanma Duncanma commented Oct 6, 2026

Copy link
Copy Markdown

Related issues

None filed. The docs team found this while reviewing docs.temporal.io: the temporal workflow reset reference shows usage examples but has no flags table.

What changed?

gen-docs wrote an option table only for leaf commands. A command that has subcommands but also declares its own options lost those options from the generated docs. code.go registers those options as persistent flags, so they apply to the command and all of its subcommands. Because the generator never documented them, they appeared on no page at all.

Two commands are affected today:

  • temporal workflow reset: all 10 flags are missing, including the required --reason, plus --event-id, --type, --workflow-id and --reapply-exclude. Its with-workflow-update-options subcommand is what turns it into a non-leaf command.
  • temporal task-queue versioning: the required --task-queue flag shared by every versioning subcommand is missing.

The fix:

  • Write the option table for any command that is a leaf or declares options of its own (hasOptionsSection). Parents that only group subcommands, or only pull in option sets, are unchanged.
  • For a non-leaf command, the lead-in sentence says the options apply to "this command and all of its subcommands", which matches the persistent-flag behavior.
  • Rename writeLeafOptions to writeOptionsSection, since it no longer handles only leaf commands.
  • The split-subdirectory paths (writeSplitCommand and writeSplitSubcommand) get the same rule. No split command hits this today.

Generated output

Before and after, I ran go run ./cmd/gen-docs -input internal/temporalcli/commands.yaml -input cliext/option-sets.yaml -output … (the same invocation as ci.yaml). The diff only adds lines: 15 in workflow.mdx under ## reset and 6 in task-queue.mdx under ## versioning. Nothing else changes.

## reset
...
Use the following options to change the behavior of this command and all of its subcommands. You can also use any of the [global flags](#global-flags) that apply to all subcommands.

| Flag | Required | Description |
|------|----------|-------------|
| `--build-id` | No | **string** A Build ID. ... |
| `--event-id`, `-e` | No | **int** Event ID to reset to. ... |
...
| `--reason` | Yes | **string** Reason for reset. |
...

Separate issue, not fixed here

processOptions pops at most one frame per command, so after a deeper subcommand the options stack stays longer than the current command's depth. Today the stale frames are always empty, so output isn't affected, which is why I left it alone. Fixing it properly also means deciding whether a parent's persistent options should count as "global flags" for a file, so it seemed better as its own change.

Checklist

Tests

  • Added unit test(s) (TestGenerateDocsFilesParentOptions). It covers single-file and -subdir output: a parent with its own options gets a table that says it applies to subcommands, and a grouping-only parent gets none. It fails without the fix.
  • Functional tests: not applicable, because this only changes the doc generator.

Manual tests

go test ./internal/commandsgen/ ./cmd/gen-docs/
go run ./cmd/gen-docs -input internal/temporalcli/commands.yaml -input cliext/option-sets.yaml -output /tmp/docs-after
grep -A16 '^## reset' /tmp/docs-after/workflow.mdx

The docs generator only wrote an option table for leaf commands. A command
that has subcommands but also declares its own options lost those options
from the docs entirely. Those options are generated as persistent flags, so
they apply to the command and every subcommand, and no other page lists them.

Today this drops all 10 flags of `temporal workflow reset` (including the
required --reason) and the required --task-queue flag of
`temporal task-queue versioning`.

Write the option table for any command that is a leaf or declares options of
its own, and say that a parent's options also apply to its subcommands.
Grouping parents with no options of their own are unchanged.
@Duncanma
Duncanma marked this pull request as ready for review October 7, 2026 18:39
@Duncanma
Duncanma requested a review from a team as a code owner October 7, 2026 18:39
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T18:43:34.718273Z 6c99b77 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6c99b7730e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

if w.isLeafCommand(c) {
w.writeLeafOptions(fileName)
if w.hasOptionsSection(c) {
w.writeOptionsSection(c, fileName)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep parent-only flags out of the global table

When an option-bearing parent is followed directly by its child, this new call emits the parent's options under its own heading, but processing the child subsequently treats that parent's optionsStack frame as globalOptions and collects it into the same file's Global Flags section. For example, a minimal app thing run / app thing run extra tree lists --target both under run and under Global Flags, where the generated text incorrectly claims it is valid for sibling commands. Intermediate persistent flags need to be excluded from the file-wide globals or otherwise prevented from being emitted a second time.

Useful? React with 👍 / 👎.

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