Merge pull request #4375 from epage/group2

fix(parser): Only add ArgGroup to ArgMatches for command-line
This commit is contained in:
Ed Page 2022-10-12 08:20:16 -05:00 committed by GitHub
commit f0223a416c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 23 additions and 45 deletions

View file

@ -152,23 +152,6 @@ impl ArgMatcher {
ma.new_val_group(); ma.new_val_group();
} }
pub(crate) fn start_occurrence_of_arg(&mut self, arg: &Arg) {
let id = arg.get_id().clone();
debug!("ArgMatcher::start_occurrence_of_arg: id={:?}", id);
let ma = self.entry(id).or_insert(MatchedArg::new_arg(arg));
debug_assert_eq!(ma.type_id(), Some(arg.get_value_parser().type_id()));
ma.set_source(ValueSource::CommandLine);
ma.new_val_group();
}
pub(crate) fn start_occurrence_of_group(&mut self, id: Id) {
debug!("ArgMatcher::start_occurrence_of_group: id={:?}", id);
let ma = self.entry(id).or_insert(MatchedArg::new_group());
debug_assert_eq!(ma.type_id(), None);
ma.set_source(ValueSource::CommandLine);
ma.new_val_group();
}
pub(crate) fn start_occurrence_of_external(&mut self, cmd: &crate::Command) { pub(crate) fn start_occurrence_of_external(&mut self, cmd: &crate::Command) {
let id = Id::from_static_ref(Id::EXTERNAL); let id = Id::from_static_ref(Id::EXTERNAL);
debug!("ArgMatcher::start_occurrence_of_external: id={:?}", id,); debug!("ArgMatcher::start_occurrence_of_external: id={:?}", id,);

View file

@ -130,7 +130,7 @@ impl MatchedArg {
} }
pub(crate) fn check_explicit(&self, predicate: &ArgPredicate) -> bool { pub(crate) fn check_explicit(&self, predicate: &ArgPredicate) -> bool {
if self.source == Some(ValueSource::DefaultValue) { if self.source.map(|s| !s.is_explicit()).unwrap_or(false) {
return false; return false;
} }

View file

@ -9,3 +9,9 @@ pub enum ValueSource {
/// Value was passed in on the command-line /// Value was passed in on the command-line
CommandLine, CommandLine,
} }
impl ValueSource {
pub(crate) fn is_explicit(self) -> bool {
self != Self::DefaultValue
}
}

View file

@ -1078,15 +1078,6 @@ impl<'cmd> Parser<'cmd> {
matcher.add_index_to(arg.get_id(), self.cur_idx.get()); matcher.add_index_to(arg.get_id(), self.cur_idx.get());
} }
// Increment or create the group "args"
for group in self.cmd.groups_for_arg(arg.get_id()) {
matcher.add_val_to(
&group,
AnyValue::new(arg.get_id().clone()),
OsString::from(arg.get_id().as_str()),
);
}
Ok(()) Ok(())
} }
@ -1499,20 +1490,15 @@ impl<'cmd> Parser<'cmd> {
self.remove_overrides(arg, matcher); self.remove_overrides(arg, matcher);
} }
matcher.start_custom_arg(arg, source); matcher.start_custom_arg(arg, source);
for group in self.cmd.groups_for_arg(arg.get_id()) { if source.is_explicit() {
matcher.start_custom_group(group, source); for group in self.cmd.groups_for_arg(arg.get_id()) {
} matcher.start_custom_group(group.clone(), source);
} matcher.add_val_to(
&group,
/// Increase occurrence of specific argument and the grouped arg it's in. AnyValue::new(arg.get_id().clone()),
fn start_occurrence_of_arg(&self, matcher: &mut ArgMatcher, arg: &Arg) { OsString::from(arg.get_id().as_str()),
// With each new occurrence, remove overrides from prior occurrences );
self.remove_overrides(arg, matcher); }
matcher.start_occurrence_of_arg(arg);
// Increment or create the group "args"
for group in self.cmd.groups_for_arg(arg.get_id()) {
matcher.start_occurrence_of_group(group);
} }
} }
} }
@ -1549,7 +1535,7 @@ impl<'cmd> Parser<'cmd> {
// Add the arg to the matches to build a proper usage string // Add the arg to the matches to build a proper usage string
if let Some((name, _)) = did_you_mean.as_ref() { if let Some((name, _)) = did_you_mean.as_ref() {
if let Some(arg) = self.cmd.get_keymap().get(&name.as_ref()) { if let Some(arg) = self.cmd.get_keymap().get(&name.as_ref()) {
self.start_occurrence_of_arg(matcher, arg); self.start_custom_arg(matcher, arg, ValueSource::CommandLine);
} }
} }

View file

@ -73,9 +73,10 @@ fn group_single_value() {
#[test] #[test]
fn group_empty() { fn group_empty() {
let res = Command::new("group") let res = Command::new("group")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color [color] "some option")) .arg(arg!(-c --color [color] "some option"))
.arg(arg!(-n --hostname <name> "another option")) .arg(arg!(-n --hostname <name> "another option"))
.group(ArgGroup::new("grp").args(["hostname", "color"])) .group(ArgGroup::new("grp").args(["hostname", "color", "flag"]))
.try_get_matches_from(vec![""]); .try_get_matches_from(vec![""]);
assert!(res.is_ok(), "{}", res.unwrap_err()); assert!(res.is_ok(), "{}", res.unwrap_err());
@ -87,12 +88,13 @@ fn group_empty() {
#[test] #[test]
fn group_required_flags_empty() { fn group_required_flags_empty() {
let result = Command::new("group") let result = Command::new("group")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color "some option")) .arg(arg!(-c --color "some option"))
.arg(arg!(-n --hostname <name> "another option")) .arg(arg!(-n --hostname <name> "another option"))
.group( .group(
ArgGroup::new("grp") ArgGroup::new("grp")
.required(true) .required(true)
.args(["hostname", "color"]), .args(["hostname", "color", "flag"]),
) )
.try_get_matches_from(vec![""]); .try_get_matches_from(vec![""]);
assert!(result.is_err()); assert!(result.is_err());
@ -103,9 +105,10 @@ fn group_required_flags_empty() {
#[test] #[test]
fn group_multi_value_single_arg() { fn group_multi_value_single_arg() {
let res = Command::new("group") let res = Command::new("group")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color <color> "some option").num_args(1..)) .arg(arg!(-c --color <color> "some option").num_args(1..))
.arg(arg!(-n --hostname <name> "another option")) .arg(arg!(-n --hostname <name> "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"]); .try_get_matches_from(vec!["", "-c", "blue", "red", "green"]);
assert!(res.is_ok(), "{:?}", res.unwrap_err().kind()); assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());