From d0dcaac2aba81852b2e3f03ad3390799a9ceac90 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 12 Oct 2022 07:39:55 -0500 Subject: [PATCH] fix(parser): Only add ArgGroup to ArgMatches for command-line This will fix `clap_derive`s behavior for optional-flattened groups as it will properly detect when the group is present (#3566). While I consider this a bug and not part of compatibility guarentees, I still want to keep in mind user impact which could still prevent this. Defaults will make the group always-present which has little value and if anything is relying on this, it is probably an application bug. --- src/parser/parser.rs | 16 +++++++++------- tests/builder/groups.rs | 9 ++++++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 62471334e50..9a224cd8849 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -1490,13 +1490,15 @@ impl<'cmd> Parser<'cmd> { self.remove_overrides(arg, matcher); } matcher.start_custom_arg(arg, source); - for group in self.cmd.groups_for_arg(arg.get_id()) { - matcher.start_custom_group(group.clone(), source); - matcher.add_val_to( - &group, - AnyValue::new(arg.get_id().clone()), - OsString::from(arg.get_id().as_str()), - ); + if source.is_explicit() { + for group in self.cmd.groups_for_arg(arg.get_id()) { + matcher.start_custom_group(group.clone(), source); + matcher.add_val_to( + &group, + AnyValue::new(arg.get_id().clone()), + OsString::from(arg.get_id().as_str()), + ); + } } } } diff --git a/tests/builder/groups.rs b/tests/builder/groups.rs index 17bd9c37b7a..2150a2b6272 100644 --- a/tests/builder/groups.rs +++ b/tests/builder/groups.rs @@ -73,9 +73,10 @@ fn group_single_value() { #[test] fn group_empty() { let res = Command::new("group") + .arg(arg!(-f --flag "some flag")) .arg(arg!(-c --color [color] "some option")) .arg(arg!(-n --hostname "another option")) - .group(ArgGroup::new("grp").args(["hostname", "color"])) + .group(ArgGroup::new("grp").args(["hostname", "color", "flag"])) .try_get_matches_from(vec![""]); assert!(res.is_ok(), "{}", res.unwrap_err()); @@ -87,12 +88,13 @@ fn group_empty() { #[test] fn group_required_flags_empty() { let result = Command::new("group") + .arg(arg!(-f --flag "some flag")) .arg(arg!(-c --color "some option")) .arg(arg!(-n --hostname "another option")) .group( ArgGroup::new("grp") .required(true) - .args(["hostname", "color"]), + .args(["hostname", "color", "flag"]), ) .try_get_matches_from(vec![""]); assert!(result.is_err()); @@ -103,9 +105,10 @@ fn group_required_flags_empty() { #[test] fn group_multi_value_single_arg() { let res = Command::new("group") + .arg(arg!(-f --flag "some flag")) .arg(arg!(-c --color "some option").num_args(1..)) .arg(arg!(-n --hostname "another option")) - .group(ArgGroup::new("grp").args(["hostname", "color"])) + .group(ArgGroup::new("grp").args(["hostname", "color", "flag"])) .try_get_matches_from(vec!["", "-c", "blue", "red", "green"]); assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());