Skip to content

shuf: report every malformed -i range the way GNU does - #14290

Open
arbelonson-source wants to merge 1 commit into
uutils:mainfrom
arbelonson-source:fix/shuf-invalid-input-range-message
Open

shuf: report every malformed -i range the way GNU does#14290
arbelonson-source wants to merge 1 commit into
uutils:mainfrom
arbelonson-source:fix/shuf-invalid-input-range-message

Conversation

@arbelonson-source

Copy link
Copy Markdown
Contributor

shuf's -i range is parsed by a clap value_parser, so every way of getting it wrong surfaces clap's wrapper and its own internal reason, rather than the utility's message.

Command GNU uutils before
shuf -i 5-1 shuf: invalid input range: '5-1' error: invalid value '5-1' for '--input-range <LO-HI>': start exceeds end
shuf -i abc shuf: invalid input range: 'abc' ... : missing '-'
shuf -i 1-abc shuf: invalid input range: '1-abc' ... : invalid digit found in string
shuf -i 1- shuf: invalid input range: '1-' ... : cannot parse integer from empty string
shuf -i -1-5 shuf: invalid input range: '-1-5' error: unexpected argument '-1' found

GNU reports all of them the same way. The last row is the odd one out: a range beginning with a hyphen never reached the range check at all, because clap rejected it as an unknown option first.

Found by differential testing against GNU coreutils 9.11.

Approach

The range is now taken verbatim, with allow_hyphen_values so a leading hyphen reaches us, and checked in uumain where the utility can emit its own message. parse_range no longer needs to explain why a range is bad, since GNU does not distinguish, so it returns Err(()) and the caller owns the wording.

Two message keys that only existed to feed clap's wrapper (shuf-error-start-exceeds-end, shuf-error-missing-dash) are replaced by the single shuf-error-invalid-input-range.

The existing tests

Four tests asserted clap's wording. I checked each input against GNU before changing them:

$ shuf -i5-3   → shuf: invalid input range: '5-3'
$ shuf -i 0    → shuf: invalid input range: '0'
$ shuf -i a-9  → shuf: invalid input range: 'a-9'
$ shuf -i 0-b  → shuf: invalid input range: '0-b'

They now assert GNU's message. A fifth test covers the hyphen-leading range that previously could not reach the check.

Testing

  • cargo test --features shuf --no-default-features: 77 passed, 0 failed (76 pre-existing/updated, 1 new)
  • Verified the tests catch the bug: reverting shuf.rs and the .ftl alone fails 4 of them
  • cargo fmt --check and cargo clippy -p uu_shuf --all-targets: clean
  • 10-case differential check against GNU 9.11, including the valid ranges that must keep working (1-3, 3-3, and the empty 5-4, which succeeds silently in both)

Disclosure

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

The range was parsed by a clap `value_parser`, so each way of getting it
wrong surfaced clap's wording and its own reason:

    $ shuf -i 5-1
    error: invalid value '5-1' for '--input-range <LO-HI>': start exceeds end

GNU reports all of them identically, as `invalid input range: '5-1'`. A
range beginning with a hyphen never even reached the check, since clap
rejected `-1-5` as an unknown option first.

Take the range verbatim, allow hyphen-leading values, and check it in
`uumain` so the utility owns the message. Four tests asserted clap's
wording and now assert GNU's; each was checked against GNU 9.11 first.
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/date/resolution (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/tail/tail-n0f is now passing!

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