Repository: clap-rs/clap
Pull request #3642 (2022-04-19 15:14:35)

feat(clap): Publicly expose `Command::build`
`Command::_build_all` started as an internal function for
`clap_complete` as a stopgap until #2911.  Overtime, we've been finding
more cases where this function needs to be called, so now we're going to
fully embrace it until #2911 so people aren't scrared off by the hidden
implementation from using it.

This was inspired by #3602

Comptibility: Though this adds a deprecation which we general reserve
for minor or major versions, this is enough of a corner case that I'm
fine doing this in a patch release.

<!--
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/clap_complete/src/generator/mod.rs b/clap_complete/src/generator/mod.rs
index 2d00c281..b33ce481 100644
--- a/clap_complete/src/generator/mod.rs
+++ b/clap_complete/src/generator/mod.rs
@@ -236,7 +236,7 @@ where
     G: Generator,
     S: Into<String>,
 {
-    cmd._build_all();
+    cmd.build();
 
     gen.generate(cmd, buf)
 }
diff --git a/clap_complete/src/generator/utils.rs b/clap_complete/src/generator/utils.rs
index b8aaa4bd..054ee2b8 100644
--- a/clap_complete/src/generator/utils.rs
+++ b/clap_complete/src/generator/utils.rs
@@ -151,14 +151,14 @@ mod tests {
     fn built() -> Command<'static> {
         let mut cmd = common_app();
 
-        cmd._build_all();
+        cmd.build();
         cmd
     }
 
     fn built_with_version() -> Command<'static> {
         let mut cmd = common_app().version("3.0");
 
-        cmd._build_all();
+        cmd.build();
         cmd
     }
 
diff --git a/clap_mangen/src/lib.rs b/clap_mangen/src/lib.rs
index 44f55840..bf11b60b 100644
--- a/clap_mangen/src/lib.rs
+++ b/clap_mangen/src/lib.rs
@@ -26,7 +26,7 @@ pub struct Man<'a> {
 impl<'a> Man<'a> {
     /// Create a new manual page.
     pub fn new(mut cmd: clap::Command<'a>) -> Self {
-        cmd._build_all();
+        cmd.build();
         let title = cmd.get_name().to_owned();
         let section = "1".to_owned();
         let date = "".to_owned();
diff --git a/src/build/command.rs b/src/build/command.rs
index 39e1b435..86da3041 100644
--- a/src/build/command.rs
+++ b/src/build/command.rs
@@ -3984,9 +3984,17 @@ impl<'help> App<'help> {
         Ok(matcher.into_inner())
     }
 
-    // used in clap_complete (https://github.com/clap-rs/clap_complete)
     #[doc(hidden)]
+    #[deprecated(since = "3.1.10", note = "Replaced with `Command::build`")]
     pub fn _build_all(&mut self) {
+        self.build();
+    }
+
+    /// Prepare for introspecting on all included [`Command`]s
+    ///
+    /// Call this on the top-level [`Command`] when done building and before reading state for
+    /// cases like completions, custom help output, etc.
+    pub fn build(&mut self) {
         self._build();
         for subcmd in self.get_subcommands_mut() {
             subcmd._build();
@@ -4047,9 +4055,13 @@ impl<'help> App<'help> {
         Some(sc)
     }
 
-    // used in clap_complete (https://github.com/clap-rs/clap_complete)
     #[doc(hidden)]
+    #[deprecated(since = "3.1.10", note = "Replaced with `Command::build`")]
     pub fn _build(&mut self) {
+        self._build_self()
+    }
+
+    pub(crate) fn _build_self(&mut self) {
         debug!("App::_build");
         if !self.settings.is_set(AppSettings::Built) {
             // Make sure all the globally set flags apply to us as well
diff --git a/src/parse/features/suggestions.rs b/src/parse/features/suggestions.rs
index 76d16ac8..77ba8c7a 100644
--- a/src/parse/features/suggestions.rs
+++ b/src/parse/features/suggestions.rs
@@ -51,7 +51,7 @@ where
         None => subcommands
             .into_iter()
             .filter_map(|subcommand| {
-                subcommand._build();
+                subcommand._build_self();
 
                 let longs = subcommand.get_keymap().keys().filter_map(|a| {
                     if let KeyType::Long(v) = a {
diff --git a/src/parse/parser.rs b/src/parse/parser.rs
index d778b845..95f027e7 100644
--- a/src/parse/parser.rs
+++ b/src/parse/parser.rs
@@ -636,7 +636,7 @@ impl<'help, 'cmd> Parser<'help, 'cmd> {
                 }
                 .clone();
 
-                sc._build();
+                sc._build_self();
                 bin_name.push(' ');
                 bin_name.push_str(sc.get_name());
             }


Test patch:
diff --git a/src/build/tests.rs b/src/build/tests.rs
index 0cea0095..76c8b878 100644
--- a/src/build/tests.rs
+++ b/src/build/tests.rs
@@ -39,7 +39,7 @@ fn issue_2090() {
     let mut cmd = Command::new("cmd")
         .disable_version_flag(true)
         .subcommand(Command::new("sub"));
-    cmd._build();
+    cmd._build_self();
 
     assert!(cmd
         .get_subcommands()
diff --git a/tests/builder/app_settings.rs b/tests/builder/app_settings.rs
index c48c9590..6c6453e4 100644
--- a/tests/builder/app_settings.rs
+++ b/tests/builder/app_settings.rs
@@ -1176,7 +1176,7 @@ fn color_is_global() {
     let mut cmd = Command::new("myprog")
         .color(clap::ColorChoice::Never)
         .subcommand(Command::new("foo"));
-    cmd._build_all();
+    cmd.build();
     assert_eq!(cmd.get_color(), clap::ColorChoice::Never);
 
     let sub = cmd.get_subcommands().collect::<Vec<_>>()[0];
diff --git a/tests/builder/help.rs b/tests/builder/help.rs
index 211f7e0d..48eb1cf2 100644
--- a/tests/builder/help.rs
+++ b/tests/builder/help.rs
@@ -2872,7 +2872,7 @@ fn disable_help_flag_affects_help_subcommand() {
     let mut cmd = Command::new("test_app")
         .disable_help_flag(true)
         .subcommand(Command::new("test").about("Subcommand"));
-    cmd._build_all();
+    cmd.build();
 
     let args = cmd
         .find_subcommand("help")
@@ -2918,7 +2918,7 @@ fn help_without_short() {
         .arg(arg!(-h --hex <NUM>))
         .arg(arg!(--help));
 
-    cmd._build_all();
+    cmd.build();
     let help = cmd.get_arguments().find(|a| a.get_id() == "help").unwrap();
     assert_eq!(help.get_short(), None);