Conversation
|
Warning Review limit reached
Next review available in: 31 minutes Limit details: You’ve used all 4 included reviews currently available under your plan. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Central YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (5)
📒 Files selected for processing (10)
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. Comment |
Greptile SummaryAdds Go usage-line rendering backed by a separately linked help table and extends conformance coverage against usage-lib’s output.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the prior nested-value bracket concern is addressed by independently deriving and testing ValueDemanded against usage-lib’s reference output. Important Files Changed
Reviews (6): Last reviewed commit: "fix(go): stabilize dumped help width" | Re-trigger Greptile |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d2ed9bd. Configure here.
Instruction countsThe comparison never ran — an earlier step failed. Shadow comparisonParsing
|
…g unused
The first half of help, and the half everything else hangs off: `argv.UsageLine`
renders what a page prints after `Usage: `.
argv.UsageLine([]string{"mise"}, mise.Root, mise.HelpText)
// mise [FLAGS] [TASK] <SUBCOMMAND>
**All 211 of mise's usage lines match usage-lib's byte for byte.** That is the
test worth having rather than a snapshot of what this happens to produce:
usage-lib builds the line from a spec through a template over a runtime model,
this builds it from static tables, and reimplemented rules drift. Both are run
over mise's real spec and compared — the same check `benches/gate/tests/help.rs`
makes for usage-argv, against the same reference. Two implementations checked
against one oracle beats two checked against each other.
Help text is a *third* table rather than more fields on `Meta`, and the reason is
the linker: Go drops an unreferenced package-level symbol whole, so one table
would make every CLI that applies a post-binding rule carry every help string in
the spec — several hundred kilobytes of them, for mise. Three tables let the
linker enforce the split that Rust gets from a feature flag, and measured at
mise's size it does: 2.60 MB binding only, 2.82 MB once something references
either cold table, no init function in any of them.
`Demanded` is precomputed into the help table rather than read from `Meta` for
the same reason — required-and-undefaulted is what decides whether the line
angles an entry or brackets it, and reaching into the post-binding table to ask
would drag it into every binary that prints help.
The fiddly parts are ported rather than reinvented, and the parity test is what
proves it: the two-entry inline limit before collapsing to `[FLAGS]`, the `…` for
a repeatable flag as distinct from a variadic value, `[-- COMMAND]…` with the
brackets outside the separator, and naming a flag whose forms do not imply its
name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… does
A review comment about `Demanded` turned out to be wrong about the reference and
right that something was off next door.
The claim was that a flag whose default sits on its nested value should not be
angled. usage-lib angles it: `<--jobs [n]>`, and accepts the invocation without
it, printing `jobs=4`. So `Demanded: true` is correct, and the tables are not
inconsistent — they answer different questions, and usage-lib gives the same two
answers.
What the case did expose is the *value's* brackets. usage-lib applies the same
required-and-undefaulted test to the value that it applies to the flag, and the
two are independent:
flag "--tool <TOOL>" → [--tool <TOOL>]
flag "--v <n>" required=#true → <--v <n>>
flag "--opt [n]" → [--opt [n]]
flag "--jobs <n>" required { arg default="4" } → <--jobs [n]>
This angled the value unconditionally, so it was wrong on three of those four.
The 211-command parity test did not catch it because every flag value mise
declares is required and undefaulted — a fixture cannot find what it does not
contain, which is the second time that has been true in this stack.
Worth recording that usage-argv angles the value unconditionally too, so it
differs from usage-lib on the same three. This follows usage-lib, which is the
reference the help output is measured against and the oracle this suite already
uses. That makes the Rust side's behaviour a finding rather than something to
copy.
The four combinations are now a test, each asserted against usage-lib's own line
as well as against the expected string — so the expectation cannot quietly become
a record of what this code does.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…them usage-go renders help from static tables where usage-lib renders it from a spec through a template, and reimplemented rules drift. `benches/gate/tests/help.rs` holds usage-argv to the standard of matching all 211 of mise's pages byte for byte; a Go suite needs the same reference, and cannot call `usage::docs::cli::render_help` because it is not Rust. Shelling out to the CLI almost works: a usage-shebang script prints a page, and mise's spec can be embedded in one. But a subcommand's page arrives wrapped in the frame miette draws around an error, and a reference that *might* have been reflowed on the way out is worse than no reference at all — the test would fail and the obvious response would be to change the implementation until it matched text nobody had rendered. So `xtask help-pages <spec.kdl>` dumps every command's short and long page as JSON, unwrapped, in one pass. One invocation rather than 211, and no frame to strip. In xtask rather than the CLI deliberately: this is a maintainer's tool for checking one implementation against another, not an output format anybody asked for. `usage generate` stays the list of things a spec author wants. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…of mise's (#974) The whole page, not just the usage line: header, `Commands`, `Arguments`, `Flags` and `Global flags`, columns lined up, inherited globals resolved the way the parser resolves them. **All 211 of mise's pages match usage-lib byte for byte.** ``` $ mise run test:go 211 short pages match usage-lib exactly 211 usage lines match usage-lib exactly ``` That is the standard [`benches/gate/tests/help.rs`](https://github.com/jdx/usage/blob/main/benches/gate/tests/help.rs) holds usage-argv to, and the only one worth having: help text is the part of a CLI a user actually reads, and a rule reimplemented from a spec-driven template into static tables drifts unless something checks every page. The reference is `xtask help-pages`, which landed in #964. ## 167 matched first run. The four that did not Each reads as arbitrary until the diff shows it: - **The short page prints an entry's whole `help`, not its first line.** mise has flags whose help is two lines, and the second appears on the page unindented. - **`(default: …)` is printed for an argument and not for a flag.** Not an oversight in usage-lib — a distinction the long page picks back up. - **The short-flag column is four wide, and only a _bare_ short goes in it.** A flag carrying a declared name its forms do not imply (`jobs: -j --parallel`) is left whole rather than split around a comma. - **A page offers a spelling only where the flag it describes is the one that would bind it.** The fiddliest part and the most load-bearing. ## That last rule, since it is the one to review A nearer command claiming `--jobs` leaves an inherited `--workers` findable. Hidden flags still reserve their spellings, because the parser still binds them. A long anywhere in scope beats a negation, because `longFlag` asks for every long form before it asks for any negation. And `--help`/`--version` are offered only under the spellings nothing else has claimed. Advertising a flag that something else binds is the lie the model exists to prevent, and none of it is visible without the parity test. ## Both halves are tested `go/conformance` proves the renderer against usage-lib using tables built from a lowered spec at run time. That leaves the emitter unchecked, and the help table is where a dropped field is least visible — a missing alias or annotation changes one line of one page. So `internal/shadow/mise` renders the whole tree from what the generator actually wrote, plus one page asserted in full. ## What is left `--help`. It wraps long descriptions and switches to a two-line layout for entries with a longer form; `ShortHelp` does neither. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Help rendering and tests only; no parser binding or security-sensitive paths changed. Risk is mainly user-visible help text regressions, guarded by byte-for-byte reference tests. > > **Overview** > Adds **`argv.ShortHelp`** to render full short help (`-h`): header, Commands, Arguments, Flags, Global flags, examples, and aligned columns. **`Help`** grows page-only fields (aliases, choices, env, defaults, before/after help, examples), and **`flagUsageShown`** / **`scope.go`** limit listed flag spellings to what the parser would bind, including inherited globals, shadowing, negations, and parser-supplied `--help` / `--version`. > > Conformance now byte-matches **all 211** mise short pages against `xtask help-pages` (`page_test.go`), compares Rust **`usage generate go`** vs runtime lowering (`producers_test.go`), and smoke-renders generated shadow tables (`meta_test.go`). README documents short help parity and notes **`--help`** long-page layout as still missing. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8b8026a. 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 complete short-help page rendering for commands. * Help pages now include aliases, examples, choices, environment variables, defaults, and custom surrounding text. * Improved display of local and inherited global flags, including supported spellings and negations. * Hidden and shadowed options are omitted from help output. * **Documentation** * Updated documentation to confirm short-help compatibility across all 211 reference pages. * **Tests** * Added conformance coverage verifying short-help pages match the reference output byte-for-byte. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

The first half of help, and the half everything else hangs off.
Follows #959, which has merged; this now targets
maindirectly.All 211 of mise's usage lines match usage-lib byte for byte
That is the test worth having, rather than a snapshot of whatever this happens to produce. usage-lib builds the line from a spec through a template over a runtime model; this builds it from static tables. Reimplemented rules drift, so both are run over mise's real spec and compared — the same check
benches/gate/tests/help.rsmakes for usage-argv, against the same reference.Two implementations checked against one oracle beats two checked against each other.
Why help text is a third table
Not more fields on
Meta. Go's linker drops an unreferenced package-level symbol whole, so one table would make every CLI that applies a post-binding rule carry every help string in the spec — several hundred kilobytes of them for mise. Three tables let the linker enforce the split Rust gets from a feature flag:+ Meta+ HelpTextNo init function in any of them.
Demandedis precomputed into the help table for the same reason: required-and-undefaulted decides the brackets, and reaching intoMetato ask would drag it into every binary that prints help.The fiddly parts
Ported rather than reinvented, with the parity test as the proof: the two-entry inline limit before collapsing to
[FLAGS], the…for a repeatable flag as distinct from a variadic value,[-- COMMAND]…with the brackets outside the separator, and naming a flag whose forms do not imply its name (env: -E… <ENV>).What is still missing
-hand--helpstill need laying out — on the Rust side that is most ofargv/src/help.rs. And errors:Error()returnsunknown flag: --wat, which names the problem and helps nobody fix it.🤖 Generated with Claude Code
Note
Low Risk
User-visible help strings only; no parser binding or auth changes, guarded by extensive parity tests.
Overview
Adds
argv.UsageLineand a separateHelp/HelpTableso the post-Usage:line is built from parse tables plus cold help metadata, without pullingMetainto binaries that only print help.Rendering follows usage-lib rules: hide entries, inline up to two flags/args then collapse to
[FLAGS]/[ARGS], required vs optional brackets (including flag values viaValueDemanded), repeatable flags,---only positionals, and subcommand suffix.Conformance adds
help_test.go: all 211 mise command usage lines are compared byte-for-byte to usage-lib’s loweredusagestrings (same oracle asbenches/gate/tests/help.rs), plus focused cases for hidden entries and flag-value bracketing.runUsageis shared for lowering specs in tests.Docs explain the three-table linker split (parse / Meta / HelpText) and what help work remains (
-hpages, richer errors).Reviewed by Cursor Bugbot for commit 5be8b7f. Bugbot is set up for automated code reviews on this repo. Configure here.