Repository: clap-rs/clap
Pull request #4710 (2023-02-15 05:28:49)

fix(help): Don't accidentally show long help with `--help` when it isn't intended.
We were accidentally showing long help just because a hidden argument had a description for a possible value.  This is most likely to be hit with the derive API as the value descriptions are automatically applied from documentation.


Patch:
diff --git a/src/builder/command.rs b/src/builder/command.rs
index 494e2356..b587fb01 100644
--- a/src/builder/command.rs
+++ b/src/builder/command.rs
@@ -4593,12 +4593,13 @@ impl Command {
         // specified by the user is sent through. If hide_short_help is not included,
         // then items specified with hidden_short_help will also be hidden.
         let should_long = |v: &Arg| {
-            v.get_long_help().is_some()
-                || v.is_hide_long_help_set()
-                || v.is_hide_short_help_set()
-                || v.get_possible_values()
-                    .iter()
-                    .any(PossibleValue::should_show_help)
+            !v.is_hide_set()
+                && (v.get_long_help().is_some()
+                    || v.is_hide_long_help_set()
+                    || v.is_hide_short_help_set()
+                    || v.get_possible_values()
+                        .iter()
+                        .any(PossibleValue::should_show_help))
         };
 
         // Subcommands aren't checked because we prefer short help for them, deferring to
diff --git a/src/builder/str.rs b/src/builder/str.rs
index c6689d31..be69c3f6 100644
--- a/src/builder/str.rs
+++ b/src/builder/str.rs
@@ -246,7 +246,10 @@ pub(crate) mod inner {
         }
 
         pub(crate) fn into_string(self) -> String {
-            self.as_str().to_owned()
+            match self {
+                Self::Static(s) => s.to_owned(),
+                Self::Owned(s) => s.into(),
+            }
         }
     }
 }


Test patch:
diff --git a/tests/builder/hidden_args.rs b/tests/builder/hidden_args.rs
index 4cdfb245..537c8fc1 100644
--- a/tests/builder/hidden_args.rs
+++ b/tests/builder/hidden_args.rs
@@ -1,6 +1,6 @@
 use super::utils;
 
-use clap::{arg, Arg, ArgAction, Command};
+use clap::{arg, builder::PossibleValue, Arg, ArgAction, Command};
 
 static HIDDEN_ARGS: &str = "\
 tests stuff
@@ -278,3 +278,27 @@ fn hide_subcmds_only() {
 
     utils::assert_output(cmd, "test --help", HIDDEN_SUBCMDS_ONLY, false);
 }
+
+#[test]
+fn hidden_arg_with_possible_value_with_help() {
+    // Normally the presence of a possible value with a help text triggers a
+    // change of the --help help text by appending `(see more with '--help')`
+    // or `(see a summary with '-h')`. When the argument is completely hidden
+    // we however do not want it to trigger that change.
+    static POS_VALS_HELP: &str = "\
+Usage: ctest
+
+Options:
+  -h, --help  Print help
+";
+    let app = Command::new("ctest").arg(
+        Arg::new("pos")
+            .hide(true)
+            .value_parser([
+                PossibleValue::new("fast"),
+                PossibleValue::new("slow").help("not as fast"),
+            ])
+            .action(ArgAction::Set),
+    );
+    utils::assert_output(app, "ctest --help", POS_VALS_HELP, false);
+}