diff --git a/src/parse/validator.rs b/src/parse/validator.rs index 4a709efc591..2a8c6618003 100644 --- a/src/parse/validator.rs +++ b/src/parse/validator.rs @@ -285,6 +285,12 @@ impl<'help, 'cmd> Validator<'help, 'cmd> { let used_filtered: Vec = matcher .arg_names() .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) + .filter(|n| { + // Filter out the args we don't want to specify. + self.cmd + .find(n) + .map_or(true, |a| !a.is_hide_set() && !self.required.contains(&a.id)) + }) .filter(|key| !conflicting_keys.contains(key)) .cloned() .collect(); diff --git a/tests/builder/main.rs b/tests/builder/main.rs index 124111f1011..35f939fd38a 100644 --- a/tests/builder/main.rs +++ b/tests/builder/main.rs @@ -42,6 +42,7 @@ mod tests; mod unicode; mod unique_args; mod utf16; +mod usage; mod utf8; mod utils; mod validators; diff --git a/tests/builder/usage.rs b/tests/builder/usage.rs new file mode 100644 index 00000000000..f634b71f926 --- /dev/null +++ b/tests/builder/usage.rs @@ -0,0 +1,37 @@ +use clap::{Arg, Command, ErrorKind}; + +fn cmd() -> Command<'static> { + Command::new("prog") + .arg(Arg::new("a").required(true)) + .arg(Arg::new("b").short('b').takes_value(true).group("debug")) + .arg(Arg::new("c").short('c').takes_value(true).group("debug")) +} + +#[test] +fn valid_cases() { + let res = cmd().try_get_matches_from(vec!["prog", "aaa"]); + assert!(res.is_ok(), "{}", res.unwrap_err()); + let res = cmd().try_get_matches_from(vec!["prog", "aaa", "-b", "bbb"]); + assert!(res.is_ok(), "{}", res.unwrap_err()); + let res = cmd().try_get_matches_from(vec!["prog", "aaa", "-c", "ccc"]); + assert!(res.is_ok(), "{}", res.unwrap_err()); +} + +/// https://github.com/clap-rs/clap/issues/3665 and https://github.com/clap-rs/clap/issues/3556 +#[test] +fn no_duplicate_required_argument_a_when_conflict() { + let res = cmd().try_get_matches_from(vec!["prog", "aaa", "-b", "bbb", "-c", "ccc"]); + assert!(res.is_err()); + let err = res.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::ArgumentConflict); + assert_eq!( + err.to_string(), + "error: The argument '-b ' cannot be used with '-c ' + +USAGE: + prog -b + +For more information try --help +" + ); +}