mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 01:35:36 +00:00
fix(cli): keep a recovered -o when a retry reaches --help or --version
Dropping an unknown argument can expose a later --help, and clap then returns no matches, losing an -o already read. Keep the last pass that read one (Pullfrog review on #56). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3syn2fN2LNo5pvTSqc6eh
This commit is contained in:
parent
70e923334d
commit
c8e79b8f7b
2 changed files with 33 additions and 7 deletions
|
|
@ -128,11 +128,21 @@ fn requested_output_from_args() -> OutputFormat {
|
|||
}
|
||||
|
||||
/// clap stops at an unknown argument, so an `-o` after it would be missed;
|
||||
/// drop each unknown argument and parse again. What is left is read with
|
||||
/// ignore_errors, which keeps the matches made before any other error.
|
||||
/// drop each unknown argument and parse again. Each pass is read with
|
||||
/// ignore_errors, which keeps the matches made before any other error; the
|
||||
/// last pass that read an `-o` wins (a later pass can reach `--help`, which
|
||||
/// returns no matches at all).
|
||||
fn output_flag(mut args: Vec<std::ffi::OsString>) -> Option<OutputSetting> {
|
||||
use clap::CommandFactory;
|
||||
use clap::error::{ContextKind, ContextValue, ErrorKind};
|
||||
let read = |args: &[std::ffi::OsString]| {
|
||||
Cli::command()
|
||||
.ignore_errors(true)
|
||||
.try_get_matches_from(args)
|
||||
.ok()
|
||||
.and_then(|matches| matches.get_one::<OutputSetting>("output").copied())
|
||||
};
|
||||
let mut found = read(&args);
|
||||
for _ in 0..args.len() {
|
||||
let Err(err) = Cli::command().try_get_matches_from(&args) else {
|
||||
break;
|
||||
|
|
@ -150,12 +160,9 @@ fn output_flag(mut args: Vec<std::ffi::OsString>) -> Option<OutputSetting> {
|
|||
break;
|
||||
};
|
||||
args.remove(index + 1);
|
||||
found = read(&args).or(found);
|
||||
}
|
||||
Cli::command()
|
||||
.ignore_errors(true)
|
||||
.try_get_matches_from(args)
|
||||
.ok()
|
||||
.and_then(|matches| matches.get_one::<OutputSetting>("output").copied())
|
||||
found
|
||||
}
|
||||
|
||||
fn bootstrap_output_format(cli: &Cli) -> OutputFormat {
|
||||
|
|
|
|||
|
|
@ -2134,6 +2134,25 @@ fn argument_errors_follow_the_output_format_clap_resolves() {
|
|||
.args(["config", "get", "--bogus", "-o", "json"]),
|
||||
"INVALIDINPUT",
|
||||
);
|
||||
// ...and so does one before it when --help or --version follows.
|
||||
for args in [
|
||||
&["-o", "json", "config", "get", "--bogus", "--help"][..],
|
||||
&["-o", "json", "--bogus", "--version"][..],
|
||||
] {
|
||||
run_error_json(
|
||||
test_bin("argument-error-json")
|
||||
.env("IDX_OUTPUT", "table")
|
||||
.args(args),
|
||||
"INVALIDINPUT",
|
||||
);
|
||||
}
|
||||
test_bin("argument-error-table")
|
||||
.env("IDX_OUTPUT", "json")
|
||||
.args(["-o", "table", "config", "get", "--bogus", "--help"])
|
||||
.assert()
|
||||
.failure()
|
||||
.stdout("")
|
||||
.stderr(predicate::str::starts_with("error: "));
|
||||
test_bin("argument-error-table")
|
||||
.args(["config", "get", "--bogus", "-o", "table"])
|
||||
.assert()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue