Repository: clap-rs/clap
Pull request #4150 (2022-08-30 19:16:39)

fix(usage): Don't include irrelevant parent args
This was identified in https://github.com/clap-rs/clap/discussions/4134

This is a backport of #4149

<!--
Thanks for helping out!

Please link the appropriate issue from your PR.

If you don't have an issue, we'd recommend starting with one first so the PR can focus on the
implementation (unless its an obvious bug or documentation fix that will have
little conversation).
-->



Patch:
diff --git a/src/builder/command.rs b/src/builder/command.rs
index 84f3cbbb..de59ad8c 100644
--- a/src/builder/command.rs
+++ b/src/builder/command.rs
@@ -4336,7 +4336,8 @@ impl<'help> App<'help> {
         use std::fmt::Write;
 
         let mut mid_string = String::from(" ");
-        if !self.is_subcommand_negates_reqs_set() {
+        if !self.is_subcommand_negates_reqs_set() && !self.is_args_conflicts_with_subcommands_set()
+        {
             let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m)
 
             for s in &reqs {
@@ -4419,7 +4420,9 @@ impl<'help> App<'help> {
 
         if !self.is_set(AppSettings::BinNameBuilt) {
             let mut mid_string = String::from(" ");
-            if !self.is_subcommand_negates_reqs_set() {
+            if !self.is_subcommand_negates_reqs_set()
+                && !self.is_args_conflicts_with_subcommands_set()
+            {
                 let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m)
 
                 for s in &reqs {


Test patch:
diff --git a/tests/builder/help.rs b/tests/builder/help.rs
index 26ad3b54..7a3d6f3a 100644
--- a/tests/builder/help.rs
+++ b/tests/builder/help.rs
@@ -829,14 +829,6 @@ fn multi_level_sc_help() {
     utils::assert_output(cmd, "ctest help subcmd multi", MULTI_SC_HELP, false);
 }
 
-#[test]
-fn no_wrap_help() {
-    let cmd = Command::new("ctest")
-        .term_width(0)
-        .override_help(MULTI_SC_HELP);
-    utils::assert_output(cmd, "ctest --help", &format!("{}\n", MULTI_SC_HELP), false);
-}
-
 #[test]
 fn no_wrap_default_help() {
     let cmd = Command::new("ctest").version("1.0").term_width(0);
@@ -2857,6 +2849,50 @@ OPTIONS:
     utils::assert_eq(EXPECTED, String::from_utf8(buf).unwrap());
 }
 
+#[test]
+fn parent_cmd_req_ignored_when_negates_reqs() {
+    static MULTI_SC_HELP: &str = "ctest-subcmd 
+
+USAGE:
+    ctest subcmd
+
+OPTIONS:
+    -h, --help    Print help information
+";
+
+    let cmd = Command::new("ctest")
+        .arg(arg!(<input>))
+        .subcommand_negates_reqs(true)
+        .subcommand(Command::new("subcmd"));
+    utils::assert_output(cmd, "ctest subcmd --help", MULTI_SC_HELP, false);
+}
+
+#[test]
+fn parent_cmd_req_ignored_when_conflicts() {
+    static MULTI_SC_HELP: &str = "ctest-subcmd 
+
+USAGE:
+    ctest subcmd
+
+OPTIONS:
+    -h, --help    Print help information
+";
+
+    let cmd = Command::new("ctest")
+        .arg(arg!(<input>))
+        .args_conflicts_with_subcommands(true)
+        .subcommand(Command::new("subcmd"));
+    utils::assert_output(cmd, "ctest subcmd --help", MULTI_SC_HELP, false);
+}
+
+#[test]
+fn no_wrap_help() {
+    let cmd = Command::new("ctest")
+        .term_width(0)
+        .override_help(MULTI_SC_HELP);
+    utils::assert_output(cmd, "ctest --help", &format!("{}\n", MULTI_SC_HELP), false);
+}
+
 #[test]
 fn display_name_default() {
     let mut cmd = Command::new("app").bin_name("app.exe");