From 07d985d8c508fabc093a3c509f5253e7081d6c0a Mon Sep 17 00:00:00 2001 From: Kevin K Date: Fri, 3 Feb 2017 15:46:25 -0500 Subject: [PATCH] Issues 839,840 (#842) * fix: fixes a critical bug where subcommand settings were being propogated too far Closes #832 * imp: adds ArgGroup::multiple to the supported YAML fields for building ArgGroups from YAML Closes #840 * chore: increase version --- CHANGELOG.md | 12 ++++++++++++ Cargo.toml | 2 +- README.md | 15 +++++++-------- src/app/parser.rs | 24 ++++++++++-------------- src/app/settings.rs | 6 +----- src/args/group.rs | 1 + 6 files changed, 32 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 032f7096..e727bee9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ + +### v2.20.2 (2017-02-03) + +#### Bug Fixes + +* fixes a critical bug where subcommand settings were being propogated too far ([74648c94](https://github.com/kbknapp/clap-rs/commit/74648c94b893df542bfa5bb595e68c7bb8167e36), closes [#832](https://github.com/kbknapp/clap-rs/issues/832)) + + +#### Improvements + +* adds ArgGroup::multiple to the supported YAML fields for building ArgGroups from YAML ([d8590037](https://github.com/kbknapp/clap-rs/commit/d8590037ce07dafd8cd5b26928aa4a9fd3018288), closes [#840](https://github.com/kbknapp/clap-rs/issues/840)) + ### v2.20.1 (2017-01-31) diff --git a/Cargo.toml b/Cargo.toml index bce15373..be77e345 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "clap" -version = "2.20.1" +version = "2.20.2" authors = ["Kevin K. "] exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"] repository = "https://github.com/kbknapp/clap-rs.git" diff --git a/README.md b/README.md index f52a8e5f..0d309daf 100644 --- a/README.md +++ b/README.md @@ -45,17 +45,16 @@ Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc) ## What's New -Here's the highlights for v2.20.1 +Here's the highlights for v2.20.2 + +* fixes a critical bug where subcommand settings were being propogated too far +* adds ArgGroup::multiple to the supported YAML fields for building ArgGroups from YAML + + +Here's the highlights from v2.0.0 to v2.20.1 * Fixes a bug where the final word wasn't wrapped in help messages -* Updates `libc` and `term_size` deps for the `libc` version conflict * Fixes finding required arguments in group arguments -* Fixes broken link from `app_from_crate!` to `crate_authors!` -* Fixes some docs spelling mistakes - - -Here's the highlights from v2.0.0 to v2.20.0 - * **ArgsNegateSubcommands:** disables args being allowed between subcommands * **DontCollapseArgsInUsage:** disables the collapsing of positional args into `[ARGS]` in the usage string * **DisableHelpSubcommand:** disables building the `help` subcommand diff --git a/src/app/parser.rs b/src/app/parser.rs index 2c2dcb73..1304b19b 100644 --- a/src/app/parser.rs +++ b/src/app/parser.rs @@ -236,35 +236,28 @@ impl<'a, 'b> Parser<'a, 'b> } pub fn add_subcommand(&mut self, mut subcmd: App<'a, 'b>) { - debugln!("Parser::add_subcommand;"); - debugln!("Parser::add_subcommand: Term width...{:?}", - self.meta.term_w); + debugln!("Parser::add_subcommand: term_w={:?}, name={}", + self.meta.term_w, subcmd.p.meta.name); subcmd.p.meta.term_w = self.meta.term_w; - debug!("Parser::add_subcommand: Is help..."); if subcmd.p.meta.name == "help" { - sdebugln!("Yes"); self.settings.unset(AppSettings::NeedsSubcommandHelp); - } else { - sdebugln!("No"); } self.subcommands.push(subcmd); } pub fn propogate_settings(&mut self) { - debugln!("Parser::propogate_settings;"); + debugln!("Parser::propogate_settings: self={}, g_settings={:#?}", + self.meta.name, self.g_settings); for sc in &mut self.subcommands { + debugln!("Parser::propogate_settings: sc={}, settings={:#?}, g_settings={:#?}", + sc.p.meta.name, sc.p.settings, sc.p.g_settings); // We have to create a new scope in order to tell rustc the borrow of `sc` is // done and to recursively call this method { let vsc = self.settings.is_set(AppSettings::VersionlessSubcommands); let gv = self.settings.is_set(AppSettings::GlobalVersion); - debugln!("Parser::propogate_settings:iter: VersionlessSubcommands set...{:?}", - vsc); - debugln!("Parser::propogate_settings:iter: GlobalVersion set...{:?}", - gv); - if vsc { sc.p.settings.set(AppSettings::DisableVersion); } @@ -273,7 +266,7 @@ impl<'a, 'b> Parser<'a, 'b> sc.p.meta.version = Some(self.meta.version.unwrap()); } sc.p.settings = sc.p.settings | self.g_settings; - sc.p.g_settings = sc.p.settings | self.g_settings; + sc.p.g_settings = sc.p.g_settings | self.g_settings; } sc.p.propogate_settings(); } @@ -982,6 +975,7 @@ impl<'a, 'b> Parser<'a, 'b> &self.create_current_usage(matcher), self.color())); } else if self.is_set(AppSettings::SubcommandRequiredElseHelp) { + debugln!("parser::get_matches_with: SubcommandRequiredElseHelp=true"); let mut out = vec![]; try!(self.write_help_err(&mut out)); return Err(Error { @@ -1124,6 +1118,8 @@ impl<'a, 'b> Parser<'a, 'b> "" }, &*sc.p.meta.name)); + println!("Parser::parse_subcommand: About to parse sc={}", sc.p.meta.name); + println!("Parser::parse_subcommand: sc settings={:#?}", sc.p.settings); try!(sc.p.get_matches_with(&mut sc_matcher, it)); matcher.subcommand(SubCommand { name: sc.p.meta.name.clone(), diff --git a/src/app/settings.rs b/src/app/settings.rs index 37cdce9f..891897b5 100644 --- a/src/app/settings.rs +++ b/src/app/settings.rs @@ -43,13 +43,9 @@ bitflags! { } #[doc(hidden)] -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct AppFlags(Flags); -// impl Clone for AppFlags { -// fn clone(&self) -> Self { AppFlags(self.0) } -// } - impl BitOr for AppFlags { type Output = Self; fn bitor(self, rhs: Self) -> Self { diff --git a/src/args/group.rs b/src/args/group.rs index b54f851c..d6cb9eb4 100644 --- a/src/args/group.rs +++ b/src/args/group.rs @@ -474,6 +474,7 @@ impl<'a> From<&'a BTreeMap> for ArgGroup<'a> { for (k, v) in group_settings.iter() { a = match k.as_str().unwrap() { "required" => a.required(v.as_bool().unwrap()), + "multiple" => a.multiple(v.as_bool().unwrap()), "args" => yaml_vec_or_str!(v, a, arg), "arg" => { if let Some(ys) = v.as_str() {