diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index ccc733e7b0b..d439ba81ab6 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -2704,23 +2704,18 @@ impl<'help> App<'help> { // Internally used only impl<'help> App<'help> { - fn get_used_global_args(&self, matcher: &ArgMatcher) -> Vec { - let global_args: Vec<_> = self - .args - .args() - .filter(|a| a.get_global()) - .map(|ga| ga.id.clone()) - .collect(); - if let Some(used_subcommand) = matcher.subcommand.as_ref() { - if let Some(used_subcommand) = self - .subcommands - .iter() - .find(|subcommand| subcommand.id == used_subcommand.id) - { - return [global_args, used_subcommand.get_used_global_args(matcher)].concat(); + fn get_used_global_args(&self, matches: &ArgMatches, global_arg_vec: &mut Vec) { + global_arg_vec.extend( + self.args + .args() + .filter(|a| a.get_global()) + .map(|ga| ga.id.clone()), + ); + if let Some((id, matches)) = matches.subcommand() { + if let Some(used_sub) = self.find_subcommand(id) { + used_sub.get_used_global_args(matches, global_arg_vec); } } - global_args } fn _do_parse(&mut self, it: &mut Input) -> ClapResult { @@ -2742,7 +2737,8 @@ impl<'help> App<'help> { } } - let global_arg_vec: Vec = self.get_used_global_args(&matcher); + let mut global_arg_vec = Default::default(); + self.get_used_global_args(&matcher, &mut global_arg_vec); matcher.propagate_globals(&global_arg_vec); diff --git a/tests/builder/global_args.rs b/tests/builder/global_args.rs index 5af286c37e5..c04468d5b80 100644 --- a/tests/builder/global_args.rs +++ b/tests/builder/global_args.rs @@ -88,3 +88,23 @@ fn global_arg_available_in_subcommand() { assert!(m.is_present("global")); assert!(m.subcommand_matches("ping").unwrap().is_present("global")); } + +#[test] +fn deeply_nested_discovery() { + let app = App::new("a").arg(arg!(--"long-a").global(true)).subcommand( + App::new("b").arg(arg!(--"long-b").global(true)).subcommand( + App::new("c") + .arg(arg!(--"long-c").global(true)) + .subcommand(App::new("d")), + ), + ); + + let m = app + .try_get_matches_from(["a", "b", "c", "d", "--long-a", "--long-b", "--long-c"]) + .unwrap(); + assert!(m.is_present("long-a")); + let m = m.subcommand_matches("b").unwrap(); + assert!(m.is_present("long-b")); + let m = m.subcommand_matches("c").unwrap(); + assert!(m.is_present("long-c")); +}