diff --git a/src/app.rs b/src/app.rs index deda76a1..685261b8 100644 --- a/src/app.rs +++ b/src/app.rs @@ -118,6 +118,7 @@ pub struct App<'a, 'v, 'ab, 'u, 'h, 'ar> { bin_name: Option, usage: Option, groups: HashMap<&'ar str, ArgGroup<'ar, 'ar>>, + global_args: Vec>, no_sc_error: bool } @@ -161,6 +162,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ bin_name: None, groups: HashMap::new(), subcmds_neg_reqs: false, + global_args: vec![], no_sc_error: false } } @@ -419,6 +421,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ min_vals: a.min_vals, max_vals: a.max_vals, help: a.help, + global: a.global, empty_vals: a.empty_vals }; if pb.min_vals.is_some() && !pb.multiple { @@ -470,11 +473,12 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ multiple: a.multiple, blacklist: None, help: a.help, + global: a.global, possible_vals: None, num_vals: a.num_vals, min_vals: a.min_vals, max_vals: a.max_vals, - val_names: a.val_names, + val_names: a.val_names.clone(), requires: None, required: a.required, empty_vals: a.empty_vals @@ -540,6 +544,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ long: a.long, help: a.help, blacklist: None, + global: a.global, multiple: a.multiple, requires: None, }; @@ -560,6 +565,12 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ } self.flags.insert(a.name, fb); } + if a.global { + if a.required { + panic!("Global arguments cannot be required.\n\n\t'{}' is marked as global and required", a.name); + } + self.global_args.push(a); + } self } @@ -749,9 +760,14 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// // Additional subcommand configuration goes here, such as other arguments... /// # .get_matches(); /// ``` - pub fn subcommand(mut self, subcmd: App<'a, 'v, 'ab, 'u, 'h, 'ar>) + pub fn subcommand(mut self, mut subcmd: App<'a, 'v, 'ab, 'u, 'h, 'ar>) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { if subcmd.name == "help" { self.needs_subcmd_help = false; } + { + while let Some(a) = self.global_args.pop() { + subcmd = subcmd.arg(a); + } + } self.subcommands.insert(subcmd.name.clone(), subcmd); self } @@ -1763,6 +1779,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ help: Some("Prints help information"), blacklist: None, multiple: false, + global: false, requires: None, }; if self.needs_short_help { @@ -1780,6 +1797,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ help: Some("Prints version information"), blacklist: None, multiple: false, + global: false, requires: None, }; if self.needs_short_version { diff --git a/src/args/arg.rs b/src/args/arg.rs index 0ecfd44c..5f0f14c9 100644 --- a/src/args/arg.rs +++ b/src/args/arg.rs @@ -133,6 +133,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { val_names: None, max_vals: None, min_vals: None, + global: false, empty_vals: true, } } @@ -173,6 +174,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { max_vals: None, val_names: None, group: None, + global: false, empty_vals: true } } @@ -330,6 +332,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { max_vals: None, min_vals: None, group: None, + global: false, empty_vals: true } } @@ -646,8 +649,9 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { self } - /// Specifies that an argument applies to and will be available to all subcommands, both - /// children, and parent commands. + /// Specifies that an argument applies to and will be available to all child subcommands. + /// + /// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands) /// /// **NOTE:** Global arguments *cannot* be required. /// diff --git a/src/args/argbuilder/flag.rs b/src/args/argbuilder/flag.rs index cf40bc3e..28673f6a 100644 --- a/src/args/argbuilder/flag.rs +++ b/src/args/argbuilder/flag.rs @@ -24,6 +24,7 @@ pub struct FlagBuilder<'n> { /// The short version (i.e. single character) /// of the argument, no preceding `-` pub short: Option, + pub global: bool, } impl<'n> Display for FlagBuilder<'n> { diff --git a/src/args/argbuilder/option.rs b/src/args/argbuilder/option.rs index 217f9062..6d4eeff5 100644 --- a/src/args/argbuilder/option.rs +++ b/src/args/argbuilder/option.rs @@ -29,7 +29,8 @@ pub struct OptBuilder<'n> { pub min_vals: Option, pub max_vals: Option, pub val_names: Option>, - pub empty_vals: bool + pub empty_vals: bool, + pub global: bool, } impl<'n> Display for OptBuilder<'n> { diff --git a/src/args/argbuilder/positional.rs b/src/args/argbuilder/positional.rs index f11b4092..167b470b 100644 --- a/src/args/argbuilder/positional.rs +++ b/src/args/argbuilder/positional.rs @@ -26,7 +26,8 @@ pub struct PosBuilder<'n> { pub num_vals: Option, pub max_vals: Option, pub min_vals: Option, - pub empty_vals: bool + pub empty_vals: bool, + pub global: bool } impl<'n> Display for PosBuilder<'n> {