mirror of
https://github.com/clap-rs/clap
synced 2024-12-13 22:32:33 +00:00
Merge pull request #2771 from mustafa-guler/master
Fix bug with duplicate error messages
This commit is contained in:
commit
1937472e0f
2 changed files with 96 additions and 3 deletions
|
@ -1,6 +1,8 @@
|
|||
// std
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
|
||||
// Internal
|
||||
use crate::{
|
||||
build::AppSettings as AS,
|
||||
|
@ -382,17 +384,19 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
|
|||
);
|
||||
let mut ret_val = Vec::new();
|
||||
|
||||
let mut unrolled_reqs = vec![];
|
||||
let mut unrolled_reqs = IndexSet::new();
|
||||
|
||||
for a in self.p.required.iter() {
|
||||
if let Some(m) = matcher {
|
||||
for aa in self.p.app.unroll_requirements_for_arg(a, m) {
|
||||
unrolled_reqs.push(aa);
|
||||
// if we don't check for duplicates here this causes duplicate error messages
|
||||
// see https://github.com/clap-rs/clap/issues/2770
|
||||
unrolled_reqs.insert(aa);
|
||||
}
|
||||
}
|
||||
// always include the required arg itself. it will not be enumerated
|
||||
// by unroll_requirements_for_arg.
|
||||
unrolled_reqs.push(a.clone());
|
||||
unrolled_reqs.insert(a.clone());
|
||||
}
|
||||
|
||||
debug!(
|
||||
|
|
89
tests/double_require.rs
Normal file
89
tests/double_require.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use clap::{App, Arg, ErrorKind};
|
||||
|
||||
static HELP: &str = "prog
|
||||
|
||||
USAGE:
|
||||
prog [FLAGS]
|
||||
|
||||
FLAGS:
|
||||
-a
|
||||
-b
|
||||
-c
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static ONLY_B_ERROR: &str = "error: The following required arguments were not provided:
|
||||
-c
|
||||
|
||||
USAGE:
|
||||
prog [FLAGS] -c -b
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
static ONLY_C_ERROR: &str = "error: The following required arguments were not provided:
|
||||
-b
|
||||
|
||||
USAGE:
|
||||
prog [FLAGS] -b -c
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
fn app() -> App<'static> {
|
||||
App::new("prog")
|
||||
.arg(
|
||||
Arg::new("a")
|
||||
.short('a')
|
||||
.required_unless_present_any(&["b", "c"])
|
||||
.conflicts_with_all(&["b", "c"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("b")
|
||||
.short('b')
|
||||
.required_unless_present("a")
|
||||
.requires("c"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("c")
|
||||
.short('c')
|
||||
.required_unless_present("a")
|
||||
.requires("b"),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_cases() {
|
||||
let res = app().try_get_matches_from(vec!["", "-a"]);
|
||||
assert!(res.is_ok());
|
||||
let res = app().clone().try_get_matches_from(vec!["", "-b", "-c"]);
|
||||
assert!(res.is_ok());
|
||||
let res = app().try_get_matches_from(vec!["", "-c", "-b"]);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn help_text() {
|
||||
let res = app().try_get_matches_from(vec!["prog", "--help"]);
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind, ErrorKind::DisplayHelp);
|
||||
println!("{}", err.to_string());
|
||||
assert_eq!(err.to_string(), HELP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_duplicate_error() {
|
||||
let res = app().try_get_matches_from(vec!["", "-b"]);
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind, ErrorKind::MissingRequiredArgument);
|
||||
assert_eq!(err.to_string(), ONLY_B_ERROR);
|
||||
|
||||
let res = app().try_get_matches_from(vec!["", "-c"]);
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind, ErrorKind::MissingRequiredArgument);
|
||||
assert_eq!(err.to_string(), ONLY_C_ERROR);
|
||||
}
|
Loading…
Reference in a new issue