From c86ac603f146bd6bd1d36939ec2ebc6800609bf4 Mon Sep 17 00:00:00 2001 From: Donough Liu Date: Thu, 5 Mar 2020 17:17:07 +0800 Subject: [PATCH 1/4] Typo --- src/build/arg/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/build/arg/mod.rs b/src/build/arg/mod.rs index 291f1504..f3d230a7 100644 --- a/src/build/arg/mod.rs +++ b/src/build/arg/mod.rs @@ -2929,7 +2929,7 @@ impl<'help> Arg<'help> { /// `--option=val1,val2,val3` is three values for the `--option` argument. If you wish to /// change the delimiter to another character you can use [`Arg::value_delimiter(char)`], /// alternatively you can turn delimiting values **OFF** by using - /// [`Arg::unset_setting(ArgSettings::UseValueDelimiter`] + /// [`Arg::unset_setting(ArgSettings::UseValueDelimiter)`] /// /// # Examples /// @@ -2954,7 +2954,7 @@ impl<'help> Arg<'help> { /// assert_eq!(m.value_of("mode"), Some("fast")); /// ``` /// [`Arg::value_delimiter(char)`]: ./struct.Arg.html#method.value_delimiter - /// [`Arg::unset_setting(ArgSettings::UseValueDelimiter`]: ./enum.ArgSettings.html#variant.UseValueDelimiter + /// [`Arg::unset_setting(ArgSettings::UseValueDelimiter)`]: ./enum.ArgSettings.html#variant.UseValueDelimiter /// [multiple values]: ./enum.ArgSettings.html#variant.MultipleValues pub fn takes_value(self, tv: bool) -> Self { if tv { From bd1b73d7c88de572140f2c0591455e394609fc65 Mon Sep 17 00:00:00 2001 From: Donough Liu Date: Thu, 5 Mar 2020 17:56:24 +0800 Subject: [PATCH 2/4] Another Typo --- src/build/app/settings.rs | 4 ++-- src/parse/parser.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/build/app/settings.rs b/src/build/app/settings.rs index 24336a35..82185fff 100644 --- a/src/build/app/settings.rs +++ b/src/build/app/settings.rs @@ -698,7 +698,7 @@ pub enum AppSettings { /// **CAUTION:** This setting can interfere with [positional/free arguments], take care when /// designing CLIs which allow inferred subcommands and have potential positional/free /// arguments whose values could start with the same characters as subcommands. If this is the - /// case, it's recommended to use settings such as [`AppSeettings::ArgsNegateSubcommands`] in + /// case, it's recommended to use settings such as [`AppSettings::ArgsNegateSubcommands`] in /// conjunction with this setting. /// /// # Examples @@ -716,7 +716,7 @@ pub enum AppSettings { /// [`subcommands`]: ./struct..html /// [positional/free arguments]: ./struct.Arg.html#method.index /// [aliases]: ./struct.App.html#method.alias - /// [`AppSeettings::ArgsNegateSubcommands`]: ./enum.AppSettings.html#variant.ArgsNegateSubcommands + /// [`AppSettings::ArgsNegateSubcommands`]: ./enum.AppSettings.html#variant.ArgsNegateSubcommands InferSubcommands, /// Specifies that the parser should not assume the first argument passed is the binary name. diff --git a/src/parse/parser.rs b/src/parse/parser.rs index bad6a62e..6009461b 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -546,6 +546,7 @@ where if !(self.is_set(AS::ArgsNegateSubcommands) && self.is_set(AS::ValidArgFound) || self.is_set(AS::AllowExternalSubcommands) || self.is_set(AS::InferSubcommands)) + // donoughliu { let cands = suggestions::did_you_mean(&*arg_os.to_string_lossy(), sc_names!(self.app)); From 79cec6a298547fb2294cbe71f8d64e61c9810aac Mon Sep 17 00:00:00 2001 From: Donough Liu Date: Thu, 5 Mar 2020 18:38:55 +0800 Subject: [PATCH 3/4] Fix misplaced subcommand matching failure emitter. Only positional args follow `--`. --- src/parse/parser.rs | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 6009461b..f98ea931 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -541,24 +541,23 @@ where // get the next value from the iterator continue; } - } - if !(self.is_set(AS::ArgsNegateSubcommands) && self.is_set(AS::ValidArgFound) - || self.is_set(AS::AllowExternalSubcommands) - || self.is_set(AS::InferSubcommands)) - // donoughliu - { - let cands = - suggestions::did_you_mean(&*arg_os.to_string_lossy(), sc_names!(self.app)); - if !cands.is_empty() { - let cands: Vec<_> = cands.iter().map(|cand| format!("'{}'", cand)).collect(); - return Err(ClapError::invalid_subcommand( - arg_os.to_string_lossy().into_owned(), - cands.join(" or "), - self.app.bin_name.as_ref().unwrap_or(&self.app.name), - &*Usage::new(self).create_usage_with_title(&[]), - self.app.color(), - )); + if !(self.is_set(AS::ArgsNegateSubcommands) && self.is_set(AS::ValidArgFound) + || self.is_set(AS::AllowExternalSubcommands) + || self.is_set(AS::InferSubcommands)) + { + let cands = + suggestions::did_you_mean(&*arg_os.to_string_lossy(), sc_names!(self.app)); + if !cands.is_empty() { + let cands: Vec<_> = cands.iter().map(|cand| format!("'{}'", cand)).collect(); + return Err(ClapError::invalid_subcommand( + arg_os.to_string_lossy().into_owned(), + cands.join(" or "), + self.app.bin_name.as_ref().unwrap_or(&self.app.name), + &*Usage::new(self).create_usage_with_title(&[]), + self.app.color(), + )); + } } } From 5b9f6197b145a277e8de491c5cd37edc98481e4d Mon Sep 17 00:00:00 2001 From: Donough Liu Date: Thu, 5 Mar 2020 20:02:48 +0800 Subject: [PATCH 4/4] Test added, Apply rustfmt --- src/parse/parser.rs | 3 ++- tests/subcommands.rs | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index f98ea931..a08e0fd4 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -549,7 +549,8 @@ where let cands = suggestions::did_you_mean(&*arg_os.to_string_lossy(), sc_names!(self.app)); if !cands.is_empty() { - let cands: Vec<_> = cands.iter().map(|cand| format!("'{}'", cand)).collect(); + let cands: Vec<_> = + cands.iter().map(|cand| format!("'{}'", cand)).collect(); return Err(ClapError::invalid_subcommand( arg_os.to_string_lossy().into_owned(), cands.join(" or "), diff --git a/tests/subcommands.rs b/tests/subcommands.rs index 823a361e..42f56d1f 100644 --- a/tests/subcommands.rs +++ b/tests/subcommands.rs @@ -283,3 +283,12 @@ fn issue_1161_multiple_hyphen_hyphen() { assert_eq!(expected, actual); } + +#[test] +fn issue_1722_not_emit_error_when_arg_follows_similar_to_a_subcommand() { + let m = App::new("myprog") + .subcommand(App::new("subcommand")) + .arg(Arg::with_name("argument")) + .try_get_matches_from(vec!["myprog", "--", "subcommand"]); + assert_eq!(m.unwrap().value_of("argument"), Some("subcommand")); +}