Print help caused by a command line error on stderr - #1156
Open
eastagiletracker wants to merge 1 commit into
Open
Print help caused by a command line error on stderr#1156eastagiletracker wants to merge 1 commit into
eastagiletracker wants to merge 1 commit into
Conversation
Argument parsing errors printed the full help message to stdout while only the one line error went to stderr. A mistyped command therefore wrote several kilobytes of help into redirected or piped output, e.g. `b2 sync > out.txt` left 9.6 kB of help text in out.txt. Help requested explicitly with --help/--help-all keeps going to stdout; only the help that accompanies an error moves to stderr.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR proposes printing the help text that accompanies a command line syntax error on stderr instead of stdout (Fixes #493). We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/281. You can sign in with your GitHub ID to claim ownership of the project.
The defect
B2ArgumentParser.error()callsself.print_help(), which writes to stdout, and only the one-lineprog: error: ...message reaches stderr throughself.exit(2, ...). Every argument parsing failure therefore emits several kilobytes of help on the success channel, so a mistyped command corrupts redirected or piped output. This is the second half of what was described in the issue thread: help requested explicitly already goes to stdout, but the help printed because of an error still goes there too.Reproduced on
masterat 87e3e14 with the installed console script:9.6 kB of help text lands in
out.txt, which is the file the user intended to hold command output, while the 75 bytes that actually describe the failure go to stderr. The same applies tob2 ... | jqand, as reported in the thread, to PowerShell, which treats the whole stream as an error.The change
error()now passessys.stderrtoprint_help(). That is the only behavioural line; the message, the exit status and the help formatting are untouched.This does change an observable CLI contract, so to be explicit about the boundary: help requested on purpose is unchanged.
--help,--help-alland<command> --helpstill write to stdout and still exit 0. Only output that accompanies a non-zero exit moves to stderr, which matches how the rest of the tool already reports errors, and which is the conventionsort,cutandwcfollow. A script that parsed help out of stdout after a failed invocation would need to read stderr, but such a script is already distinguishing the case by exit status 2.After the change:
Verification
Three regression cases were added to
test/unit/console_tool/test_help.py, covering an unrecognised top-level argument, missing required arguments, and an unrecognised subcommand argument. Each asserts that stdout is empty and that the error text and the option list are on stderr. They fail on the unmodified tree and pass with the change:A companion test asserts the control case — that
--helpstill writes to stdout and leaves stderr empty — and passes in both states, so the two paths are pinned apart rather than merely moved.The full unit suite was run before and after on the same tree: 378 passed before, 382 passed after (the four added cases), with an identical failure set both times. Two
test_install_autocompletecases fail on this machine before any change, from the local shell configuration, and are unrelated.ruff checkandruff format --checkpass on both touched files. Achangelog.dfragment is included per CONTRIBUTING.How this was managed
Your issues, pull requests and milestones were imported onto an agile board — 1112 stories and 17 labels — and this work was tracked there as some b2 clip help requests write to stderr instead of stdout, on the board at https://eastagiletracker.com/projects/281.
If you'd rather not receive contributions like this, reply
no-more-prson this pull request and we won't open any further ones on your repositories.Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com