feat(Global Args): allows args that propagate down to child commands

Closes #131
This commit is contained in:
Kevin K 2015-05-22 13:02:11 -04:00
parent 28b7385552
commit 2bcc6137a8
5 changed files with 31 additions and 6 deletions

View file

@ -118,6 +118,7 @@ pub struct App<'a, 'v, 'ab, 'u, 'h, 'ar> {
bin_name: Option<String>, bin_name: Option<String>,
usage: Option<String>, usage: Option<String>,
groups: HashMap<&'ar str, ArgGroup<'ar, 'ar>>, groups: HashMap<&'ar str, ArgGroup<'ar, 'ar>>,
global_args: Vec<Arg<'ar, 'ar, 'ar, 'ar, 'ar, 'ar>>,
no_sc_error: bool 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, bin_name: None,
groups: HashMap::new(), groups: HashMap::new(),
subcmds_neg_reqs: false, subcmds_neg_reqs: false,
global_args: vec![],
no_sc_error: false 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, min_vals: a.min_vals,
max_vals: a.max_vals, max_vals: a.max_vals,
help: a.help, help: a.help,
global: a.global,
empty_vals: a.empty_vals empty_vals: a.empty_vals
}; };
if pb.min_vals.is_some() && !pb.multiple { 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, multiple: a.multiple,
blacklist: None, blacklist: None,
help: a.help, help: a.help,
global: a.global,
possible_vals: None, possible_vals: None,
num_vals: a.num_vals, num_vals: a.num_vals,
min_vals: a.min_vals, min_vals: a.min_vals,
max_vals: a.max_vals, max_vals: a.max_vals,
val_names: a.val_names, val_names: a.val_names.clone(),
requires: None, requires: None,
required: a.required, required: a.required,
empty_vals: a.empty_vals 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, long: a.long,
help: a.help, help: a.help,
blacklist: None, blacklist: None,
global: a.global,
multiple: a.multiple, multiple: a.multiple,
requires: None, 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); 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 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... /// // Additional subcommand configuration goes here, such as other arguments...
/// # .get_matches(); /// # .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> { -> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
if subcmd.name == "help" { self.needs_subcmd_help = false; } 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.subcommands.insert(subcmd.name.clone(), subcmd);
self self
} }
@ -1763,6 +1779,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
help: Some("Prints help information"), help: Some("Prints help information"),
blacklist: None, blacklist: None,
multiple: false, multiple: false,
global: false,
requires: None, requires: None,
}; };
if self.needs_short_help { 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"), help: Some("Prints version information"),
blacklist: None, blacklist: None,
multiple: false, multiple: false,
global: false,
requires: None, requires: None,
}; };
if self.needs_short_version { if self.needs_short_version {

View file

@ -133,6 +133,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
val_names: None, val_names: None,
max_vals: None, max_vals: None,
min_vals: None, min_vals: None,
global: false,
empty_vals: true, empty_vals: true,
} }
} }
@ -173,6 +174,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
max_vals: None, max_vals: None,
val_names: None, val_names: None,
group: None, group: None,
global: false,
empty_vals: true empty_vals: true
} }
} }
@ -330,6 +332,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
max_vals: None, max_vals: None,
min_vals: None, min_vals: None,
group: None, group: None,
global: false,
empty_vals: true empty_vals: true
} }
} }
@ -646,8 +649,9 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
self self
} }
/// Specifies that an argument applies to and will be available to all subcommands, both /// Specifies that an argument applies to and will be available to all child subcommands.
/// children, and parent commands. ///
/// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands)
/// ///
/// **NOTE:** Global arguments *cannot* be required. /// **NOTE:** Global arguments *cannot* be required.
/// ///

View file

@ -24,6 +24,7 @@ pub struct FlagBuilder<'n> {
/// The short version (i.e. single character) /// The short version (i.e. single character)
/// of the argument, no preceding `-` /// of the argument, no preceding `-`
pub short: Option<char>, pub short: Option<char>,
pub global: bool,
} }
impl<'n> Display for FlagBuilder<'n> { impl<'n> Display for FlagBuilder<'n> {

View file

@ -29,7 +29,8 @@ pub struct OptBuilder<'n> {
pub min_vals: Option<u8>, pub min_vals: Option<u8>,
pub max_vals: Option<u8>, pub max_vals: Option<u8>,
pub val_names: Option<Vec<&'n str>>, pub val_names: Option<Vec<&'n str>>,
pub empty_vals: bool pub empty_vals: bool,
pub global: bool,
} }
impl<'n> Display for OptBuilder<'n> { impl<'n> Display for OptBuilder<'n> {

View file

@ -26,7 +26,8 @@ pub struct PosBuilder<'n> {
pub num_vals: Option<u8>, pub num_vals: Option<u8>,
pub max_vals: Option<u8>, pub max_vals: Option<u8>,
pub min_vals: Option<u8>, pub min_vals: Option<u8>,
pub empty_vals: bool pub empty_vals: bool,
pub global: bool
} }
impl<'n> Display for PosBuilder<'n> { impl<'n> Display for PosBuilder<'n> {