feat(cli): accept on/off/1/0 for boolean flags via BoolishValueParser - #703
Conversation
|
Note Reviews pausedUse the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (18)
WalkthroughThe PR replaces the removed ChangesCLI boolean parser migration
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Comment |
|
@coderabbitai pause |
✅ Action performedReviews paused. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #703 +/- ##
=======================================
Coverage 94.06% 94.06%
=======================================
Files 178 178
Lines 108601 108595 -6
=======================================
- Hits 102153 102151 -2
+ Misses 6448 6444 -4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ada6a49 to
c61ed4f
Compare
c61ed4f to
fbd9db1
Compare
Replace the hand-rolled `parse_bool` with clap's `BoolishValueParser` at all 44 boolean `#[arg]` sites, and delete the function. The accepted set is a strict superset: `on`, `off`, `1`, and `0` join the existing `true`/`false`/`yes`/`no`/`y`/`n`/`t`/`f`, all case-insensitive. Nothing that parsed before parses differently now. Unrecognized input is still rejected -- the parser returns an error rather than falling back to `true`, which clap's own `str_to_bool` doc comment misleadingly suggests. `parse_bool` documented itself as matching sopt/fgbio, and widening past that set is the one real consequence here. It is deliberate: the flags gain the spellings users coming from other CLIs reach for first, and both directions of the change are pinned by tests. Each site also gains `hide_possible_values = true` and `value_name = "true|false"`, which are one decision rather than two. Without the first, clap advertises `[possible values: true, false]`, because it hides the other ten literals -- help that names two of the twelve accepted spellings is worse than help that names none. But suppressing that line makes the placeholder the only in-help signal about what the flag takes, and clap derives that placeholder from the field name: `--memory-per-thread [<MEMORY_PER_THREAD>]` reads as a request for a per-thread memory size and invites `--memory-per-thread 10G`. were left deriving it, so the same flag rendered two ways depending on which command you asked -- `QueueMemoryOptions::memory_per_thread` is flattened into dedup, group, filter, clip, correct, and the consensus callers. `--allow-unmapped` was worse, setting `ALLOW_UNMAPPED` explicitly. All 44 now render `[<true|false>]`. The two rstest tables that covered `parse_bool` directly now drive the same cases through `TestBoolFlags::try_parse_from`, so they assert the CLI contract rather than a private function and survive another change of parser. `on`/`off`/`1`/`0` moved from the rejected table to the accepted one -- that migration is the behaviour change, made explicit. `test_bool_args_name_their_accepted_values` (from #690) still guards `Sort` alone and identifies boolean args by the `num_args = 0..=1` proxy rather than by their parser; both are addressed in a follow-up, now that `Arg::get_possible_values()` surfaces the boolish literal set. Note `crates/fgumi-cli-common` (on main-runall, not here) carries a second copy of `parse_bool` per the landing tracker's duplication ledger. It must not be reinstated as the live parser when the umbrella points at that crate. cargo ci-fmt/ci-lint clean; 6891 tests pass, 27 skipped. Help rendering verified on the built binary across sort, filter, dedup, group, clip, correct, and simplex.
fbd9db1 to
2dbfbb7
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
Follow-up to the question raised in #690: should we prefer
BoolishValueParser?What changes
parse_boolis replaced by clap'sBoolishValueParserat all 44 boolean#[arg]sites, and the function is deleted. Each of those 44 sites also gainsvalue_name = "true|false", extending repo-wide the convention #690 established forSort's three flags.truefalseyesnoyntfonoff10A strict superset, verified against
clap_builder-4.6.2:TRUE_LITERALSandFALSE_LITERALScontain all eight previous spellings. Nothing that parsed before parses differently.Unrecognized input is still rejected. Worth stating explicitly because clap's own doc comment on
str_to_boolclaims "Any other value will be considered astrue" — that comment is wrong. The function returnsNone, andBoolishValueParser::parse_refmaps that to a validation error. Confirmed on the binary:--memory-per-thread 10Gerrors.The tradeoff, stated plainly
parse_booldocumented itself as "Matches sopt/fgbio behavior", so this deliberately diverges from sopt's accepted set — that is the one real consequence, and it is the point of the change rather than a side effect. The flags now take the spellings users coming from other CLIs reach for first.The other cost named in #690 was the error message. Ours was
Invalid boolean value '10G'. Expected: true|false|yes|no|y|n|t|f; clap's isinvalid value '10G' for '--memory-per-thread [<true|false>]': value was not a boolean. Less enumerative, but it names the offending flag, which ours never did.hide_possible_valuesand the placeholderThese two are one decision, which is why the
value_namesweep rides here rather than in a follow-up.BoolishValueParser::possible_values()yields all twelve literals but marks ten hidden, so help would print[possible values: true, false]— advertising two of the twelve accepted spellings, which is worse than advertising none. Each site therefore setshide_possible_values = true.That suppression makes the placeholder the only in-help signal about what the flag takes, and without
value_nameclap derives it from the field name.--memory-per-thread [<MEMORY_PER_THREAD>]reads as a request for a per-thread memory size and invites--memory-per-thread 10G. #690 fixed that for the three flags onSort; the remaining 41 were left rendering the derived name, so the same flag rendered two different ways depending on which command you asked —QueueMemoryOptions::memory_per_threadis flattened intodedup,group,filter,clip,correct, and the consensus callers.--allow-unmappedwas worse still: it setvalue_name = "ALLOW_UNMAPPED"explicitly.Verified on the built binary across
sort,filter,dedup,group,clip,correct, andsimplex: every one now renders--memory-per-thread [<true|false>], no[possible values: ...]line appears anywhere, and no upper-snake placeholder survives on a boolean flag.Tests
The two rstest tables that called
parse_booldirectly now drive the same cases throughTestBoolFlags::try_parse_from, asserting the CLI contract rather than a private function, so they survive another change of parser.on/off/1/0moved from the rejected table to the accepted one. That migration is the behaviour change, made explicit rather than implied — a third table,test_extended_bool_values_in_cli_invalid, asserted those four were rejected, and it failed on the first run of this change exactly as it should have.test_bool_args_name_their_accepted_values(added by #690) still guardsSortonly, and it identifies boolean args by the structural proxynum_args = 0..=1rather than by their parser. Both are addressed in a follow-up PR stacked on this one:Arg::get_possible_values()now surfacesBoolishValueParser's literal set, so the test can identify boolean args exactly and walk every command instead ofSort.cargo ci-fmt/ci-lintclean.Note for the runall landing series
feat-runallandmain-runallare deliberately not changed here.main-runallinherits this forsrc/lib/commands/on its next rebase, but two copies ofparse_boolsurvive on that side and must not become the live parser —crates/fgumi-cli-common/src/lib.rs:526(landed by #672) andcrates/fgumi-sort-cli/src/sort.rs(lands at P4). Both are recorded in the landing tracker's duplication ledger so the port converts them rather than reintroducing the function.Risk: command output changes: none;
unsafechanges: none, andCLAUDE.mdallowlist updates: none; memory bounds, queue capacity, and thread/backpressure policy changes: none.Replaced the custom
parse_boolparser at 44 CLI boolean argument sites with clap’sBoolishValueParser.Boolean arguments now accept
true,false,yes,no,y,n,t,f,on,off,1, and0. Invalid values remain rejected.Standardized boolean help output with
value_name = "true|false"and hidden possible values.Updated CLI parsing tests for the expanded value set and invalid input. Formatting, lint, tests, and help rendering pass.