Rust CLI: exit 2 for usage errors, matching the Node CLI - #331
Closed
poiley wants to merge 4 commits into
Closed
Conversation
…tion The Rust port exited 1 for every failure, while the Node CLI exits 2 for usage errors (unknown command, unknown flag, missing flag value, invalid or conflicting inputs) and 1 for runtime failures. Scripts that branch on that distinction would silently break when switching CLIs, and the parity fixtures had to encode the divergence in 11 expectByRunner waivers. Adds a transparent UsageError marker in config.rs (shared with the include-style integration tests) plus a usage_err! macro; main_entry picks the exit code by inspecting the error chain, so stderr output is unchanged. Converted sites: generated-command invocation parsing and parameter validation, unknown command/subcommand/alias resolution across all command families, unknown flag and missing flag value parsers, send body-source conflicts, and the functions logs --follow/--cursor conflict. Validation paths where the Node CLI also exits 1 (describe unknown operation, config mutations, doctor) are intentionally left at 1. The 11 fixture waivers now assert exitCode 2 on both runners; waivers whose node and rust expectations became identical are collapsed into the shared expect block (expectByRunner 84 -> 77). Validation: make rust-cli-check, cli-parity (315 cases), node-check, cli-check, go-check, shared-check, rust-cli-full-check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Confidence Score: 5/5This looks safe to merge.
|
| Filename | Overview |
|---|---|
| cli-rust/src/auth_commands.rs | Auth command parsing now marks invalid argument forms with the usage-error path. |
| cli-rust/src/config.rs | Adds the usage-error marker, macro, and exit-code helper used by the Rust CLI. |
| cli-rust/src/lib.rs | Wires the Rust CLI entry path to choose the process exit code from the error chain. |
Reviews (3): Last reviewed commit: "Mark post-parse invocation-shape errors ..." | Re-trigger Greptile
Greptile review: missing-value and bool-with-inline-value branches in the hand-rolled per-command parsers (and api.rs parse_invocation, called directly by payments) still returned unmarked errors and exited 1. Convert Missing value for --X, Flag --X does not take a value, Flag --X expects a value, Expected a boolean for --X, and Unexpected argument to usage errors so every invalid-invocation path exits 2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Greptile round 2: validation that runs after flag parsing succeeds but still rejects the invocation shape (missing or extra positionals, missing required companion flags like --accept-terms or an email address for --signup-code, conflicting verification-code sources, --code-from-stdin on a TTY, config use arity, functions init arity, Unexpected argument across all hand-rolled parsers) now carries the usage marker and exits 2. State-dependent failures intentionally stay at exit 1: pending-auth email mismatch, no pending signup found, not logged in, unreadable --code-from-file targets, unset --code-from-env variables, and browser login denial, matching the Node CLI per the existing parity fixtures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Superseded by #332. The base branch was force-rebased (18e9f0c -> f1b5005) which made this PR unmergeable, and the rebased port already includes a CliError usage-error mechanism covering part of what this PR did. #332 rebuilds the remainder on the new base: ~100 uncovered parse/validation sites, auth post-parse checks, and chain-walking exit-code detection. |
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.
Summary
Follow-up to the Rust CLI port: align usage-error exit codes with the Node CLI.
The port exited
1for every failure, while the Node CLI (oclif) exits2for usage errors and1for runtime failures. Scripts and agents that branch on that distinction would silently break when switching CLIs, and the parity fixtures had to encode the divergence in 11expectByRunnerwaivers (all 11 werenode: exitCode 2vsrust: exitCode 1).What changed
UsageErrormarker +usage_err!macro incli-rust/src/config.rs(lives there so the include-style integration tests resolve it), re-exported fromlib.rs.main_entrypicks the exit code by inspecting the error chain, so stderr output is byte-identical to before; only the exit code changes.execute_operationboundary), unknown command/subcommand/alias resolution across all command families, unknown-flag and missing-flag-value parsers,sendbody-source conflicts, andfunctions logs --follow/--cursorconflict.describeunknown operation,configmutation validation,doctorfailures.exitCode: 2on both runners. Where the node and rust expectations became identical the waiver is collapsed into the sharedexpectblock (expectByRunnercount 84 -> 77).context()wrapping, Display pass-through.Validation
make rust-cli-check(fmt, clippy-D warnings, doc, tests)make cli-paritygreen: 315/315 cases, command-surface parity, operation coverage, help sweep with--compare-flagsmake node-check cli-check go-check shared-checkmake rust-cli-full-check🤖 Generated with Claude Code