From ecddecec6221174dc0557b0cbea9a6322f7e77e3 Mon Sep 17 00:00:00 2001 From: Kyle Corbeille Date: Wed, 5 Aug 2026 19:15:17 -0500 Subject: fix(cli): accept --flag=value and reordered options in pane read/wait-output (#2183) * fix(cli): accept --flag=value and reordered options in pane read/wait-output * test(cli): trim redundant pane parser coverage --------- Co-authored-by: Can Celik --- src/cli.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'src/cli.rs') diff --git a/src/cli.rs b/src/cli.rs index 4d3c67c0..6acbfcbe 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -913,6 +913,25 @@ pub(super) fn parse_u64_flag(flag: &str, value: &str) -> std::io::Result { .map_err(|_| std::io::Error::other(format!("invalid value for {flag}: {value}"))) } +/// Expand `--flag=value` tokens into separate `--flag` and `value` tokens so +/// the hand-rolled subcommand parsers accept the same `--flag=value` form the +/// clap-generated help and completions imply. Only `value_options` are split: +/// boolean and unknown options keep their attached value so they still reach +/// the parser's unknown-option branch. +pub(super) fn expand_equals_args(args: &[String], value_options: &[&str]) -> Vec { + let mut expanded = Vec::with_capacity(args.len()); + for arg in args { + match arg.split_once('=') { + Some((flag, value)) if value_options.contains(&flag) => { + expanded.push(flag.to_string()); + expanded.push(value.to_string()); + } + _ => expanded.push(arg.clone()), + } + } + expanded +} + fn parse_session_json_only(args: &[String], usage: &str) -> Result { match args { [] => Ok(false), @@ -1121,4 +1140,29 @@ mod tests { ); assert!(!super::server_not_running::was_reported(&mapped)); } + + #[test] + fn expand_equals_args_splits_value_options_only() { + // Known value options split; values may contain `=`. Boolean and + // unknown options keep the attached form so parsers still reject them. + let args = vec![ + "--match=a=b".to_string(), + "name=value".to_string(), + "--raw=value".to_string(), + "--bogus=value".to_string(), + "--timeout=5000".to_string(), + ]; + assert_eq!( + super::expand_equals_args(&args, &["--match", "--timeout"]), + vec![ + "--match", + "a=b", + "name=value", + "--raw=value", + "--bogus=value", + "--timeout", + "5000", + ] + ); + } } -- cgit v1.2.3