Skip to content

numfmt: report bad --round and --invalid values the way --from does - #14292

Closed
arbelonson-source wants to merge 2 commits into
uutils:mainfrom
arbelonson-source:fix/numfmt-round-invalid-argument-message
Closed

numfmt: report bad --round and --invalid values the way --from does#14292
arbelonson-source wants to merge 2 commits into
uutils:mainfrom
arbelonson-source:fix/numfmt-round-invalid-argument-message

Conversation

@arbelonson-source

Copy link
Copy Markdown
Contributor

--round and --invalid were restricted by a clap value_parser, so a bad value surfaced clap's wording — while --from and --to, which are checked in code, already used GNU's:

$ numfmt --round=bogus 1
error: invalid value 'bogus' for '--round <METHOD>'      # clap
$ numfmt --from=bogus 1
numfmt: invalid argument 'bogus' for '--from'            # GNU's wording, already correct
Command GNU uutils before
numfmt --round=bogus 1 numfmt: invalid argument 'bogus' for '--round' error: invalid value 'bogus' for '--round <METHOD>'
numfmt --invalid=bogus 1 numfmt: invalid argument 'bogus' for '--invalid' error: invalid value 'bogus' for '--invalid <INVALID>'
numfmt --round= 1 numfmt: ambiguous argument '' for '--round' error: invalid value '' for '--round <METHOD>'

Found by differential testing against GNU coreutils 9.11.

Approach

Both are now checked in code, reusing the existing OptionValueError and numfmt-error-invalid-unit-argument message that parse_unit already uses, so all four options report consistently.

Two details the value_parser was quietly handling:

  • Abbreviations. ShortcutValueParser accepted any unambiguous prefix, and so does GNU — --round=f is from-zero, --invalid=ig is ignore. resolve_choice preserves that. The existing test_round covers from-zer and would have caught its loss.
  • Ambiguity. An empty value matches every choice at once, and GNU distinguishes that: ambiguous argument '' rather than invalid argument ''. A message is added for it.

Scope, stated honestly

GNU also prints a second line after this one, Valid arguments are: followed by the list. uutils' existing --from/--to message does not, so this brings --round and --invalid in line with numfmt's own convention and matches GNU's first line — it is not full GNU parity for any of the four. The help line each error carries (--round takes up, down, from-zero, towards-zero or nearest) serves a similar purpose in uutils' style.

The same clap-vs-GNU wording gap exists in wc --total=bogus; left out to keep this to one utility.

Testing

  • 14-case differential check against GNU 9.11: all match, including the abbreviations and every valid value that had to keep working
  • New test_invalid_round_and_invalid_arguments, verified to fail without the change
  • cargo test --features numfmt --no-default-features: 159 passed, 0 failed (158 pre-existing, 1 new)
  • cargo fmt --check and cargo clippy -p uu_numfmt --all-targets: clean

Disclosure

Prepared with AI assistance (Claude Opus 5, via Claude Code), per the AI policy in CONTRIBUTING.md. The GNU messages were established by running the installed GNU binary as a black box; I did not read GNU coreutils source. All testing was run locally.

Both were restricted by a clap `value_parser`, so a bad value surfaced
clap's wording while `--from` and `--to`, checked in code, already used
GNU's:

    $ numfmt --round=bogus 1
    error: invalid value 'bogus' for '--round <METHOD>'   # clap
    $ numfmt --from=bogus 1
    numfmt: invalid argument 'bogus' for '--from'         # GNU's wording

Check them in code as well, reusing `OptionValueError` and the existing
`numfmt-error-invalid-unit-argument` message.

`ShortcutValueParser` was also accepting unambiguous abbreviations, and
GNU accepts them too (`--round=f` is from-zero), so `resolve_choice`
keeps that. An empty value matches every choice at once, which GNU
reports as `ambiguous argument` rather than `invalid argument`; that
message is added.
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/tail/tail-n0f (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Skip an intermittent issue tests/pr/bounded-memory (was skipped on 'main', now failing)

`.args(&[&format!(...), "1"])` mixes a `&String` and a `&str` in one
array literal; `args<S>` needs a single `S` for both, so this never
compiled -- CI catches it, `cargo test -p uu_numfmt` alone does not,
since the standalone crate's test binary isn't the one that builds this
file. Two `.arg()` calls sidestep the type unification instead of
fighting it.
@arbelonson-source

Copy link
Copy Markdown
Contributor Author

Closing proactively — this is the same pattern maintainers flagged on #14308/#14312/#14305/#14306: clap's own wording for --round/--invalid is already correct, this PR only reworded it to match GNU's text. Sorry for not catching this pattern before opening it.

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