From 6a11d61ab40aa7128b3be7d68a0f960fc5ca4b38 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Sat, 9 Jul 2022 00:36:06 -0600 Subject: [PATCH] fix: Include groups in `get_arg_conflicts_with` So that it doesn't panic if trying to get the conflicts for an Arg that conflicts with a group. Fixes: #3900 --- src/builder/command.rs | 22 +++++++++++++--------- tests/builder/conflicts.rs | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/builder/command.rs b/src/builder/command.rs index d644cb7681fa..f4dc3fab0510 100644 --- a/src/builder/command.rs +++ b/src/builder/command.rs @@ -3556,15 +3556,19 @@ impl<'help> App<'help> { if arg.is_global_set() { self.get_global_arg_conflicts_with(arg) } else { - arg.blacklist - .iter() - .map(|id| { - self.args.args().find(|arg| arg.id == *id).expect( - "Command::get_arg_conflicts_with: \ - The passed arg conflicts with an arg unknown to the cmd", - ) - }) - .collect() + let mut result = Vec::new(); + for id in arg.blacklist.iter() { + if let Some(arg) = self.find(id) { + result.push(arg); + } else if let Some(group) = self.find_group(id) { + result.extend(self.unroll_args_in_group(&group.id).iter().map(|id| { + self.find(id).expect(INTERNAL_ERROR_MSG) + })); + } else { + panic!("Command::get_arg_conflicts_with: The passed arg conflicts with an arg unknown to the cmd"); + } + } + result } } diff --git a/tests/builder/conflicts.rs b/tests/builder/conflicts.rs index 3c0ef817b9e7..cb5e7da7aec8 100644 --- a/tests/builder/conflicts.rs +++ b/tests/builder/conflicts.rs @@ -296,6 +296,24 @@ fn required_group_conflicts_with_arg() { } } +#[test] +fn get_arg_conflicts_with_group() { + let flag = arg!(--flag).conflicts_with("gr"); + let mut cmd = Command::new("group_conflict") + .arg(&flag) + .group(ArgGroup::new("gr").arg("some").arg("other")) + .arg(arg!(--some)) + .arg(arg!(--other)); + + cmd.build(); + + let result = cmd.get_arg_conflicts_with(&flag); + + assert_eq!(result.len(), 2); + assert_eq!(result[0].get_id(), "some"); + assert_eq!(result[1].get_id(), "other"); +} + #[test] fn conflict_output() { utils::assert_output(