Skip to content

Commit 45dcf0e

Browse files
committed
fix(parser): Don't make Args exclusive with their ArgGroup
This is most obvious with the derive API as it creates `ArgGroup`s all over the place now. Fixes clap-rs#4396
1 parent a40c7b4 commit 45dcf0e

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

Diff for: src/parser/validator.rs

+3
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ impl<'cmd> Validator<'cmd> {
112112
.arg_ids()
113113
.filter(|arg_id| {
114114
matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
115+
// Avoid including our own groups by checking none of them. If a group is present, the
116+
// args for the group will be.
117+
&& self.cmd.find(arg_id).is_some()
115118
})
116119
.count();
117120
if args_count <= 1 {

Diff for: tests/builder/conflicts.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,13 @@ fn flag_conflict_with_all() {
3838

3939
#[test]
4040
fn exclusive_flag() {
41-
let result = Command::new("flag_conflict")
41+
let cmd = Command::new("flag_conflict")
4242
.arg(arg!(-f --flag "some flag").exclusive(true))
43-
.arg(arg!(-o --other "some flag"))
44-
.try_get_matches_from(vec!["myprog", "-o", "-f"]);
43+
.arg(arg!(-o --other "some flag"));
44+
let result = cmd.clone().try_get_matches_from(vec!["myprog", "-f"]);
45+
assert!(result.is_ok(), "{}", result.unwrap_err());
46+
47+
let result = cmd.clone().try_get_matches_from(vec!["myprog", "-o", "-f"]);
4548
assert!(result.is_err());
4649
let err = result.err().unwrap();
4750
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
@@ -71,6 +74,20 @@ fn not_exclusive_with_defaults() {
7174
assert!(result.is_ok(), "{}", result.unwrap_err());
7275
}
7376

77+
#[test]
78+
fn not_exclusive_with_group() {
79+
let cmd = Command::new("test")
80+
.group(clap::ArgGroup::new("test").arg("foo"))
81+
.arg(
82+
clap::Arg::new("foo")
83+
.long("foo")
84+
.exclusive(true)
85+
.action(clap::ArgAction::SetTrue),
86+
);
87+
let result = cmd.try_get_matches_from(vec!["test", "--foo"]);
88+
assert!(result.is_ok(), "{}", result.unwrap_err());
89+
}
90+
7491
#[test]
7592
fn default_doesnt_activate_exclusive() {
7693
let result = Command::new("flag_conflict")

0 commit comments

Comments
 (0)