Skip to content

fix(argv): show choices when a subcommand is required - #947

Merged
jdx merged 1 commit into
mainfrom
agent/argv-missing-subcommand-help
Aug 17, 2026
Merged

fix(argv): show choices when a subcommand is required#947
jdx merged 1 commit into
mainfrom
agent/argv-missing-subcommand-help

Conversation

@jdx

@jdx jdx commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Summary

  • render the command's short help page when a required subcommand is missing
  • keep the parse failure and exit status unchanged
  • add diagnostic coverage for the command list

This restores the discoverability users expect from Clap: running a command that requires a subcommand shows the available choices instead of only saying that a subcommand is missing.

Stack

Targets the duplicate-flag PR and is the new direct base for #936.

Checks

  • cargo test -p usage-argv --features diagnostics
  • cargo test -p usage-conformance --test help_request --test subcommand_required
  • full stacked cargo test --all --all-features
  • full stacked Clippy with warnings denied

This PR was generated by Codex.


Note

Low Risk
User-facing stderr text only on a parse-error path; parse failure and exit status stay the same, with a safe fallback if help rendering fails.

Overview
When parsing stops with Error::MissingSubcommand, diagnostics now try help::render_at for the current command path and return that short help (including the Commands: list) instead of the old “requires a subcommand” line plus a usage block.

If help cannot be rendered, behavior falls back to the previous error message. A unit test asserts the new output lists subcommands like use and user and omits the old wording.

Reviewed by Cursor Bugbot for commit ae19f7b. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • User Experience
    • When a required subcommand is omitted, the command now displays its help page with available subcommands.
    • The previous “requires a subcommand” error and usage block are no longer shown in this case.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a73664c-c059-4717-b666-94b4452a6555

📥 Commits

Reviewing files that changed from the base of the PR and between 10b5f1f and 16e0387.

📒 Files selected for processing (1)
  • argv/src/diagnostic.rs

Included review availability: Your plan includes up to 4 reviews per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Error::MissingSubcommand now renders the parsed command’s help page. The regression test verifies that the help lists use and user and excludes the previous missing-subcommand error.

Changes

Missing subcommand help

Layer / File(s) Summary
Help rendering and regression coverage
argv/src/diagnostic.rs
Error::MissingSubcommand returns help::render_at output. The regression test verifies the use and user commands and excludes the old error text.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 16e03

Missing required subcommands will now show available choices while preserving the parse failure and exit status; no actionable merge-blocking risk remains.

Poem

I’m a rabbit with a help page bright,
Missing commands now show what’s right.
use and user hop into view,
The old error text is gone from the queue.
Carrots for tests—one, two, three!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the change to show available choices when a required subcommand is missing.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR changes missing-subcommand diagnostics to render the relevant command’s short help while preserving parse failure behavior and the existing fallback.

  • Shows available subcommands when a required subcommand is omitted.
  • Adds diagnostic coverage for the command list and removal of the generic error text.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
argv/src/diagnostic.rs MissingSubcommand now returns short help when route resolution succeeds, retains the prior error-and-usage fallback, and adds focused output assertions.

Reviews (3): Last reviewed commit: "fix(argv): show choices when a subcomman..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Instruction counts

Nothing was compared, and so nothing was gated. No series appears on both sides: either the base has no measurements recorded, or the two were measured on different runner classes, which are deliberately not comparable — counts shift between machine types by more than a real regression does.

New, nothing to compare against: markdown on bamboo-v2-ubuntu24.04-x64-30vcpu-24gb-rust1.97.1, startup on bamboo-v2-ubuntu24.04-x64-30vcpu-24gb-rust1.97.1

Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run.

Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.

Shadow comparison

Parsing mise use -g node@20 against a shadow of mise's committed spec.
Reported, not gated: the shadow grows as the derive learns to express more, so
what to watch is the ratio rather than either column.

usage clap ratio
instructions, cold parse 64525 5893640 91x
usage: argv -> struct                            1071 ns      1.07 µs
clap: build tree + parse -> struct             500106 ns    500.11 µs
clap: parse -> struct, tree reused              23591 ns     23.59 µs
clap: build tree only                          310190 ns    310.19 µs

ae19f7bbca20 vs 60b4357913a5 · measured on the runner, not pushed to the history.

Base automatically changed from agent/argv-duplicate-flags to main August 17, 2026 04:26
@jdx
jdx force-pushed the agent/argv-missing-subcommand-help branch from a2c44cd to 16e0387 Compare August 17, 2026 04:26
@jdx
jdx force-pushed the agent/argv-missing-subcommand-help branch from 16e0387 to ae19f7b Compare August 17, 2026 04:42
@jdx
jdx merged commit 921efbd into main Aug 17, 2026
11 checks passed
@jdx
jdx deleted the agent/argv-missing-subcommand-help branch August 17, 2026 10:18
jdx added a commit that referenced this pull request Aug 17, 2026
## Summary

- accept `#[usage(verbatim_doc_comment)]` on root and command structs,
fields, and subcommand variants
- preserve internal line breaks, blank lines, indentation, and
whitespace in derived help
- retain the conventional removal of one leading space after `///` and
outer blank lines
- document the attribute and cover root, flag, and subcommand metadata

This keeps Clap declarations that use ASCII art, tables, examples, or
deliberately formatted prose intact during migration.

## Stack

Targets #947 and becomes the direct base for #936.

## Checks

- `cargo test -p usage-conformance --test metadata`
- `cargo test -p usage-derive`
- `cargo test --all --all-features`
- `cargo clippy --all --all-features --all-targets -- -D warnings`
- `mise run render`

_This PR was generated by Codex._

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Changes are confined to derive-time help text extraction with default
behavior preserved; risk is limited to help/spec wording, covered by new
conformance tests.
> 
> **Overview**
> Adds **`#[usage(verbatim_doc_comment)]`** on root/`Args` structs,
fields, and subcommand variants so doc comments can feed **help/about
text with intentional line breaks, blank lines, and indentation**
instead of flowing the first paragraph like prose.
> 
> The derive’s **`doc_comment`** helper now takes a verbatim flag:
default behavior is unchanged (first paragraph collapsed to one line for
short help; multiline `#[doc = "..."]` still behaves as before). With
verbatim, it strips only the usual `///` leading space and outer blank
lines, then splits **short help** at the first blank line and keeps the
full text for **long help** when there is more.
> 
> Crate docs list the new option; **conformance metadata tests** cover
root, flag, and subcommand specs plus ordinary vs verbatim multiline
`#[doc]` attributes.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
641c80c. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
jdx added a commit that referenced this pull request Aug 17, 2026
…#965)

Stacked on #963, the `usage-rs` facade.

`usage` is now its own first adopter. Its command structs, root, and
command enums use the `usage-rs` facade instead of Clap, and
`--usage-spec` prints `Cli::to_kdl()` from the same tables that parsed
the command line.

## What goes away

- `clap`, `clap_usage`, and the `clap-sort` dev dependency
- `tests/clap_sort.rs`; declaration order is held by the spec
- the duplicated command-effect tables; effects now live on the commands
they describe
- the empty `Sponsors` struct; unit subcommands are supported directly
- runtime checks for relationships the spec can express

## Migration shape

The declarations remain close to their former Clap layout:

- inferred shorts use `#[usage(short, long)]`
- command aliases live on their command structs, e.g. `#[usage(alias =
"c", alias_hidden("complete", "completions"))]`
- positive dependencies use `requires`, including `--cache-key` →
`--usage-cmd` and `--out-dir` → `--multi`
- aliases written on enum variants still merge with struct aliases for
compatibility
- deliberately formatted docs keep `#[usage(verbatim_doc_comment)]`
- path hints keep `value_hint = usage_rs::ValueHint::FilePath` or
`DirPath` from usage’s own runtime type
- subcommand payloads stay unboxed as they were under Clap; `Box<T>`
remains an optional size optimization

The four shell commands are separate derived structs flattening a shared
group. A single destination struct cannot identify which enum variant
selected it, so a macro keeps their common declaration in one place.

## Parity gaps closed by the stack

- required subcommands survive KDL generation (#937)
- strict unknown-flag behavior is inherited by subcommands (#939)
- command-owned visible and hidden aliases are supported (#946)
- duplicate non-repeatable flags are rejected (#945)
- a missing required subcommand prints the available command choices
(#947)
- verbatim doc-comment layout is preserved on commands, fields, and
variants (#949)
- file and directory value hints reach native and emitted completions
(#951)

The emitted spec still intentionally gains metadata the Clap bridge
dropped, including `JDX_USAGE_BIN` on `--usage-bin`, preserved multiline
long help, the manpage description, and the correct binary name `usage`.

## Verification

- `mise run render`
- `cargo test --all --all-features`
- `cargo clippy --all --all-features --all-targets -- -D warnings`
- direct binary checks for no-argument help, duplicate flags, command
aliases, and positive requirements

_This PR was generated by Codex._

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes how the primary `usage` CLI is parsed and documented
(including `--completions` UX), but behavior is covered by updated
integration tests and is an intentional migration to the shipped parser.
> 
> **Overview**
> The **`usage` binary dogfoods `usage-rs`**: command structs use
`#[derive(usage_rs::Cli)]` / `#[usage(...)]` instead of Clap, and
**`--usage-spec` emits `Cli::to_kdl()`** from the same parse tables that
handle argv. **Clap, `clap_usage`, and `clap-sort` are removed**, along
with the post-hoc **`command_effects` patch table**—`effect`,
`requires`, `overrides`, and similar metadata now live on the
declarations.
> 
> **Root CLI shape is corrected in spec and docs**: **`--completions
<SHELL>` is a long flag** (not a positional), with an **explicit
multi-line `usage` synopsis** for `usage <COMMAND>` / `--completions` /
`--usage-spec`. Shell runner commands (`bash`, `fish`, `zsh`,
`powershell`, `exec`) use **`unknown_flags = "value"`** so script
arguments can include unknown flags.
> 
> **Help and manpages** gain support for an optional root **`usage`
string** on `Spec` (derive + KDL emission); root help/man synopsis
prefer that over generated lines. Generated assets (`usage.usage.kdl`,
`usage.1`, Fig spec, CLI reference markdown, snapshots) are refreshed to
match.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3aba1aa. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added `--completions <SHELL>` for selecting a completion shell.
* Improved command validation, aliases, defaults, environment settings,
and file-output completion hints.
  * Shell commands now forward unrecognized arguments as script values.
  * Added clearer help text and descriptions for generation commands.

* **Documentation**
* Updated CLI references, manpages, usage specifications, and shell
documentation to reflect revised options and behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Replaces #936 after flipping the facade and CLI layers.

---------

Co-authored-by: Claude Opus 5 <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