fix(cli): list valid taps on bad --tap, make --help uniform across subcommands
Two CLI-UX defects the Stage-1 R fieldtest surfaced (#131): 1. Tap discovery. `aura chart <name> --tap <bad>` rejected an unknown tap but the error omitted the valid names. filter_to_tap now enumerates the run's available taps in the message ("... (available: equity, exposure)"), so the user can correct a typo instead of guessing -- refuse, but help. 2. Uniform --help. `aura chart --help` errored with "unexpected chart argument '--help'" (exit 2) and `aura run --help` leaked usage to stderr via the error path, while bare `aura --help` printed to stdout (exit 0). main() now intercepts `--help`/`-h` anywhere in the invocation, prints usage to stdout, and exits 0 -- uniform for every subcommand. The now-dead bare-flag match arm is removed (the early intercept covers it). RED-first: the existing chart_tap_nonexistent test gains an available-taps assertion (was: message had no names), and a new per_subcommand_help test pins `aura <sub> --help` -> stdout usage + exit 0 for run/chart/sweep/walkforward/ mc/graph/runs (was: chart --help exited 2). Unknown-subcommand stays exit 2. Verified: clippy --all-targets -D warnings clean; full suite 514 passed / 0 failed (one new test); live `aura chart --help` prints usage to stdout, exit 0. closes #131
This commit is contained in:
@@ -467,10 +467,12 @@ fn build_comparison_chart_data(
|
||||
/// run has no such tap (refuse-don't-guess). Used by the `--tap` flag on the
|
||||
/// single-run chart path; without `--tap` the single-run page is unchanged.
|
||||
fn filter_to_tap(data: ChartData, tap: &str) -> Result<ChartData, String> {
|
||||
let series: Vec<Series> = data.series.into_iter().filter(|s| s.name == tap).collect();
|
||||
if series.is_empty() {
|
||||
return Err(format!("run has no tap named '{tap}'"));
|
||||
if !data.series.iter().any(|s| s.name == tap) {
|
||||
// List the valid taps so the user can correct a typo (#131) — refuse, but help.
|
||||
let available: Vec<&str> = data.series.iter().map(|s| s.name.as_str()).collect();
|
||||
return Err(format!("run has no tap named '{tap}' (available: {})", available.join(", ")));
|
||||
}
|
||||
let series: Vec<Series> = data.series.into_iter().filter(|s| s.name == tap).collect();
|
||||
let mut meta = data.meta;
|
||||
meta.taps = vec![tap.to_string()];
|
||||
Ok(ChartData { xs: data.xs, series, meta })
|
||||
@@ -1966,6 +1968,13 @@ fn main() {
|
||||
// so an unexpected trailing token falls through to the usage-error path rather
|
||||
// than masquerading as a successful run (#16 strict reading).
|
||||
let args: Vec<String> = std::env::args().skip(1).collect();
|
||||
// A `--help` / `-h` anywhere prints usage to stdout and exits 0, uniformly across
|
||||
// subcommands (#131): `aura chart --help` shows usage instead of erroring
|
||||
// "unexpected argument", and the bare `aura --help` is the same affordance.
|
||||
if args.iter().any(|a| a == "--help" || a == "-h") {
|
||||
println!("{USAGE}");
|
||||
return;
|
||||
}
|
||||
match args.iter().map(String::as_str).collect::<Vec<_>>().as_slice() {
|
||||
["run", rest @ ..] => match parse_run_args(rest) {
|
||||
Ok(args) => match run_dispatch(args) {
|
||||
@@ -2012,7 +2021,6 @@ fn main() {
|
||||
["runs", "families"] => runs_families(),
|
||||
["runs", "family", id] => runs_family(id, None),
|
||||
["runs", "family", id, "rank", metric] => runs_family(id, Some(metric)),
|
||||
["--help"] | ["-h"] => println!("{USAGE}"),
|
||||
_ => {
|
||||
eprintln!("aura: {USAGE}");
|
||||
std::process::exit(2);
|
||||
|
||||
Reference in New Issue
Block a user