Repository: clap-rs/clap
Pull request #4340 (2022-10-03 21:06:12)

fix(derive): Apply doc comments for `#[command(subcommand)]`
This was broken in 8a5a9ba931dd45a4976a5600eb24a91b202472f3.  I had
missed this case for parsing doc comments.


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 9324b242..086a6f2a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -143,7 +143,7 @@ dependencies = [
  "once_cell",
  "rustversion",
  "shlex",
- "snapbox",
+ "snapbox 0.4.0",
  "static_assertions",
  "strsim",
  "termcolor",
@@ -174,7 +174,7 @@ dependencies = [
  "os_str_bytes",
  "pathdiff",
  "shlex",
- "snapbox",
+ "snapbox 0.4.0",
  "trycmd",
  "unicode-xid",
 ]
@@ -185,7 +185,7 @@ version = "4.0.0"
 dependencies = [
  "clap 4.0.8",
  "clap_complete",
- "snapbox",
+ "snapbox 0.4.0",
 ]
 
 [[package]]
@@ -221,7 +221,7 @@ version = "0.2.2"
 dependencies = [
  "clap 4.0.8",
  "roff",
- "snapbox",
+ "snapbox 0.4.0",
 ]
 
 [[package]]
@@ -800,9 +800,9 @@ checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803"
 
 [[package]]
 name = "snapbox"
-version = "0.4.0"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f98a96656eecd1621c5830831b48eb6903a9f86aaeb61b9f358a9bd462414ddd"
+checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7"
 dependencies = [
  "concolor",
  "normalize-line-endings",
@@ -813,6 +813,19 @@ dependencies = [
  "yansi",
 ]
 
+[[package]]
+name = "snapbox"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f98a96656eecd1621c5830831b48eb6903a9f86aaeb61b9f358a9bd462414ddd"
+dependencies = [
+ "concolor",
+ "normalize-line-endings",
+ "similar",
+ "snapbox-macros",
+ "yansi",
+]
+
 [[package]]
 name = "snapbox-macros"
 version = "0.3.0"
@@ -915,9 +928,9 @@ dependencies = [
 
 [[package]]
 name = "trycmd"
-version = "0.13.7"
+version = "0.13.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5377b33cbe8bb69d97da63e2a2266065a642a47cc9bb3d783c28279d0029fea"
+checksum = "9ac9fa73959e252e7c5a4e6260544b952f5bf3989e0b7ad229f4fd6f14671b02"
 dependencies = [
  "escargot",
  "glob",
@@ -926,7 +939,7 @@ dependencies = [
  "rayon",
  "serde",
  "shlex",
- "snapbox",
+ "snapbox 0.3.3",
  "toml_edit",
 ]
 
diff --git a/clap_derive/src/item.rs b/clap_derive/src/item.rs
index 8b60b1f8..68af9d62 100644
--- a/clap_derive/src/item.rs
+++ b/clap_derive/src/item.rs
@@ -143,7 +143,7 @@ impl Item {
         let parsed_attrs = ClapAttr::parse_all(&variant.attrs);
         res.infer_kind(&parsed_attrs);
         res.push_attrs(&parsed_attrs);
-        if matches!(&*res.kind, Kind::Command(_)) {
+        if matches!(&*res.kind, Kind::Command(_) | Kind::Subcommand(_)) {
             res.push_doc_comment(&variant.attrs, "about", true);
         }
 
@@ -155,6 +155,9 @@ impl Item {
                         "methods are not allowed for flattened entry"
                     );
                 }
+
+                // ignore doc comments
+                res.doc_comment = vec![];
             }
 
             Kind::Subcommand(_)
@@ -228,6 +231,9 @@ impl Item {
                         "methods are not allowed for flattened entry"
                     );
                 }
+
+                // ignore doc comments
+                res.doc_comment = vec![];
             }
 
             Kind::Subcommand(_) => {
diff --git a/src/builder/arg_group.rs b/src/builder/arg_group.rs
index a6386a1c..459cc7f5 100644
--- a/src/builder/arg_group.rs
+++ b/src/builder/arg_group.rs
@@ -188,23 +188,6 @@ impl ArgGroup {
         self
     }
 
-    /// Getters for all args. It will return a vector of `Id`
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use clap::{ArgGroup};
-    /// let args: Vec<&str> = vec!["a1".into(), "a4".into()];
-    /// let grp = ArgGroup::new("program").args(&args);
-    ///
-    /// for (pos, arg) in grp.get_args().enumerate() {
-    ///     assert_eq!(*arg, args[pos]);
-    /// }
-    /// ```
-    pub fn get_args(&self) -> impl Iterator<Item = &Id> {
-        self.args.iter()
-    }
-
     /// Allows more than one of the [`Arg`]s in this group to be used. (Default: `false`)
     ///
     /// # Examples
@@ -257,23 +240,6 @@ impl ArgGroup {
         self
     }
 
-    /// Return true if the group allows more than one of the arguments
-    /// in this group to be used. (Default: `false`)
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use clap::{ArgGroup};
-    /// let mut group = ArgGroup::new("myprog")
-    ///     .args(["f", "c"])
-    ///     .multiple(true);
-    ///
-    /// assert!(group.is_multiple());
-    /// ```
-    pub fn is_multiple(&mut self) -> bool {
-        self.multiple
-    }
-
     /// Require an argument from the group to be present when parsing.
     ///
     /// This is unless conflicting with another argument.  A required group will be displayed in
@@ -572,25 +538,4 @@ mod test {
         fn foo<T: Send + Sync>(_: T) {}
         foo(ArgGroup::new("test"))
     }
-
-    #[test]
-    fn arg_group_expose_is_multiple_helper() {
-        let args: Vec<Id> = vec!["a1".into(), "a4".into()];
-
-        let mut grp_multiple = ArgGroup::new("test_multiple").args(&args).multiple(true);
-        assert!(grp_multiple.is_multiple());
-
-        let mut grp_not_multiple = ArgGroup::new("test_multiple").args(&args).multiple(false);
-        assert!(!grp_not_multiple.is_multiple());
-    }
-
-    #[test]
-    fn arg_group_expose_get_args_helper() {
-        let args: Vec<Id> = vec!["a1".into(), "a4".into()];
-        let grp = ArgGroup::new("program").args(&args);
-
-        for (pos, arg) in grp.get_args().enumerate() {
-            assert_eq!(*arg, args[pos]);
-        }
-    }
 }


Test patch:
diff --git a/tests/derive/doc_comments_help.rs b/tests/derive/doc_comments_help.rs
index d90a04bc..d6d3db3d 100644
--- a/tests/derive/doc_comments_help.rs
+++ b/tests/derive/doc_comments_help.rs
@@ -14,7 +14,7 @@
 
 use crate::utils;
 
-use clap::{CommandFactory, Parser, ValueEnum};
+use clap::{CommandFactory, Parser, Subcommand, ValueEnum};
 
 #[test]
 fn doc_comments() {
@@ -248,3 +248,31 @@ fn doc_comment_about_handles_both_abouts() {
     // comment.
     assert_eq!(cmd.get_long_about(), None);
 }
+
+#[test]
+fn respect_subcommand_doc_comment() {
+    #[derive(Parser, Debug)]
+    pub enum Cmd {
+        /// For child
+        #[command(subcommand)]
+        Child(Child),
+    }
+
+    #[derive(Subcommand, Debug)]
+    pub enum Child {
+        One,
+        Twp,
+    }
+
+    const OUTPUT: &str = "\
+Usage: cmd <COMMAND>
+
+Commands:
+  child  For child
+  help   Print this message or the help of the given subcommand(s)
+
+Options:
+  -h, --help  Print help information
+";
+    utils::assert_output::<Cmd>("cmd --help", OUTPUT, false);
+}