Propagate global arg in subcommand to subsubcommand

This commit is contained in:
Donough Liu 2020-12-12 21:55:49 +08:00
parent 76effbd8f9
commit fa9be84b18
2 changed files with 77 additions and 7 deletions

View file

@ -2261,6 +2261,26 @@ impl<'help> App<'help> {
// Internally used only
impl<'help> App<'help> {
fn get_used_global_args(&self, matcher: &ArgMatcher) -> Vec<Id> {
let global_args: Vec<_> = self
.args
.args
.iter()
.filter(|a| a.global)
.map(|ga| ga.id.clone())
.collect();
if let Some(used_subcommand) = matcher.0.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();
}
}
global_args
}
fn _do_parse(&mut self, it: &mut Input) -> ClapResult<ArgMatches> {
debug!("App::_do_parse");
let mut matcher = ArgMatcher::default();
@ -2275,13 +2295,7 @@ impl<'help> App<'help> {
let mut parser = Parser::new(self);
parser.get_matches_with(&mut matcher, it)?;
let global_arg_vec: Vec<Id> = self
.args
.args
.iter()
.filter(|a| a.global)
.map(|ga| ga.id.clone())
.collect();
let global_arg_vec: Vec<Id> = self.get_used_global_args(&matcher);
matcher.propagate_globals(&global_arg_vec);

View file

@ -29,3 +29,59 @@ fn issue_1076() {
let _ = app.try_get_matches_from_mut(vec!["myprog"]);
let _ = app.try_get_matches_from_mut(vec!["myprog"]);
}
#[test]
fn propagate_global_arg_in_subcommand_to_subsubcommand_1385() {
let m1 = App::new("foo")
.subcommand(
App::new("sub1")
.arg(Arg::new("arg1").long("arg1").takes_value(true).global(true))
.subcommand(App::new("sub1a")),
)
.get_matches_from(&["foo", "sub1", "--arg1", "v1", "sub1a"]);
assert_eq!(
"v1",
m1.subcommand_matches("sub1")
.unwrap()
.subcommand_matches("sub1a")
.unwrap()
.value_of("arg1")
.unwrap()
);
}
#[test]
fn propagate_global_arg_in_subcommand_to_subsubcommand_2053() {
let m = App::new("opts")
.arg(Arg::from("--global-flag").global(true))
.arg(
Arg::from("--global-str <global-str>")
.required(false)
.global(true),
)
.subcommand(
App::new("test")
.arg(Arg::from("--sub-flag").global(true))
.arg(
Arg::from("--sub-str <sub-str>")
.required(false)
.global(true),
)
.subcommand(App::new("test")),
)
.get_matches_from(&[
"app",
"test",
"test",
"--global-flag",
"--global-str",
"hello",
"--sub-flag",
"--sub-str",
"world",
]);
assert_eq!(
Some("world"),
m.subcommand_matches("test").unwrap().value_of("sub-str")
);
}