Repository: clap-rs/clap
Pull request #3473 (2022-02-15 14:01:23)

fix: Change `IntoApp::into_app` to `CommandFactory::command`
This is a follow up to #3472 and is part of resolving #3089.

With `Command` renamed, we need to handle the renaming of `IntoApp::into_app`.  `into_*` functions are meant to take `self` as a parameter (see https://rust-lang.github.io/api-guidelines/naming.html#c-conv) which this does not.  I think switching to `command` is sufficient for the function.  That leaves naming the trait.  Java has given a lot of us a negative feeling towards the name `Factory` but calling this a `CommandFactory` is the best, descriptive name I've been able to come up with.

For compatibility, we `pub use CommandFactory as IntoApp` and have `command()` be an inherent function that calls the deprecated `into_app`.  While in #3472, I shied away from using `use` because it doesn't trigger the deprecation warning, this was the best option I had for a trait.  This at least ensures all new users will use the new name and existing users are getting the opportunity to migrate, even if they won't get a notification.


Patch:
diff --git a/clap_complete/examples/value_hints_derive.rs b/clap_complete/examples/value_hints_derive.rs
index 2d069c28..ed24e7ed 100644
--- a/clap_complete/examples/value_hints_derive.rs
+++ b/clap_complete/examples/value_hints_derive.rs
@@ -12,7 +12,7 @@
 //! . ./value_hints_derive.fish
 //! ./target/debug/examples/value_hints_derive --<TAB>
 //! ```
-use clap::{Command, IntoApp, Parser, ValueHint};
+use clap::{Command, CommandFactory, Parser, ValueHint};
 use clap_complete::{generate, Generator, Shell};
 use std::ffi::OsString;
 use std::io;
@@ -65,7 +65,7 @@ fn main() {
     let opt = Opt::parse();
 
     if let Some(generator) = opt.generator {
-        let mut cmd = Opt::into_app();
+        let mut cmd = Opt::command();
         eprintln!("Generating completion file for {:?}...", generator);
         print_completions(generator, &mut cmd);
     } else {
diff --git a/clap_derive/src/derives/into_app.rs b/clap_derive/src/derives/into_app.rs
index cae57ea1..31973575 100644
--- a/clap_derive/src/derives/into_app.rs
+++ b/clap_derive/src/derives/into_app.rs
@@ -56,7 +56,8 @@ pub fn gen_for_struct(
             clippy::suspicious_else_formatting,
         )]
         #[deny(clippy::correctness)]
-        impl #impl_generics clap::IntoApp for #struct_name #ty_generics #where_clause {
+        #[allow(deprecated)]
+        impl #impl_generics clap::CommandFactory for #struct_name #ty_generics #where_clause {
             fn into_app<'b>() -> clap::Command<'b> {
                 let #app_var = clap::Command::new(#name);
                 <Self as clap::Args>::augment_args(#app_var)
@@ -101,7 +102,7 @@ pub fn gen_for_enum(enum_name: &Ident, generics: &Generics, attrs: &[Attribute])
             clippy::suspicious_else_formatting,
         )]
         #[deny(clippy::correctness)]
-        impl #impl_generics clap::IntoApp for #enum_name #ty_generics #where_clause {
+        impl #impl_generics clap::CommandFactory for #enum_name #ty_generics #where_clause {
             fn into_app<'b>() -> clap::Command<'b> {
                 #[allow(deprecated)]
                 let #app_var = clap::Command::new(#name)
diff --git a/clap_derive/src/dummies.rs b/clap_derive/src/dummies.rs
index a0e0ad3e..be158306 100644
--- a/clap_derive/src/dummies.rs
+++ b/clap_derive/src/dummies.rs
@@ -18,7 +18,8 @@ pub fn parser_enum(name: &Ident) {
 
 pub fn into_app(name: &Ident) {
     append_dummy(quote! {
-        impl clap::IntoApp for #name {
+        #[allow(deprecated)]
+        impl clap::CommandFactory for #name {
             fn into_app<'b>() -> clap::Command<'b> {
                 unimplemented!()
             }
diff --git a/examples/tutorial_derive/04_04_custom.rs b/examples/tutorial_derive/04_04_custom.rs
index 6541dd86..d42d22bd 100644
--- a/examples/tutorial_derive/04_04_custom.rs
+++ b/examples/tutorial_derive/04_04_custom.rs
@@ -1,4 +1,4 @@
-use clap::{ErrorKind, IntoApp, Parser};
+use clap::{CommandFactory, ErrorKind, Parser};
 
 #[derive(Parser)]
 #[clap(author, version, about, long_about = None)]
@@ -41,7 +41,7 @@ fn main() {
     // See if --set-ver was used to set the version manually
     let version = if let Some(ver) = cli.set_ver.as_deref() {
         if cli.major || cli.minor || cli.patch {
-            let mut cmd = Cli::into_app();
+            let mut cmd = Cli::command();
             cmd.error(
                 ErrorKind::ArgumentConflict,
                 "Can't do relative and absolute version change",
@@ -57,7 +57,7 @@ fn main() {
             (false, true, false) => minor += 1,
             (false, false, true) => patch += 1,
             _ => {
-                let mut cmd = Cli::into_app();
+                let mut cmd = Cli::command();
                 cmd.error(
                     ErrorKind::ArgumentConflict,
                     "Cam only modify one version field",
@@ -80,7 +80,7 @@ fn main() {
             // 'or' is preferred to 'or_else' here since `Option::as_deref` is 'const'
             .or(cli.spec_in.as_deref())
             .unwrap_or_else(|| {
-                let mut cmd = Cli::into_app();
+                let mut cmd = Cli::command();
                 cmd.error(
                     ErrorKind::MissingRequiredArgument,
                     "INPUT_FILE or --spec-in is required when using --config",
diff --git a/examples/tutorial_derive/05_01_assert.rs b/examples/tutorial_derive/05_01_assert.rs
index 52dd5d2c..12fdba9b 100644
--- a/examples/tutorial_derive/05_01_assert.rs
+++ b/examples/tutorial_derive/05_01_assert.rs
@@ -16,6 +16,6 @@ fn main() {
 
 #[test]
 fn verify_app() {
-    use clap::IntoApp;
-    Cli::into_app().debug_assert()
+    use clap::CommandFactory;
+    Cli::command().debug_assert()
 }
diff --git a/src/build/command.rs b/src/build/command.rs
index 5e95fd68..873650df 100644
--- a/src/build/command.rs
+++ b/src/build/command.rs
@@ -40,7 +40,7 @@ use crate::build::debug_asserts::assert_app;
 /// arguments (or lack thereof).
 ///
 /// When deriving a [`Parser`][crate::Parser], you can use
-/// [`IntoApp::into_app`][crate::IntoApp::into_app] to access the
+/// [`CommandFactory::into_app`][crate::CommandFactory::into_app] to access the
 /// `Command`.
 ///
 /// # Examples
diff --git a/src/derive.rs b/src/derive.rs
index 6edb9621..7436a7c0 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -12,7 +12,7 @@ use std::ffi::OsString;
 /// into concrete instance of the user struct.
 ///
 /// This trait is primarily a convenience on top of [`FromArgMatches`] +
-/// [`IntoApp`] which uses those two underlying traits to build the two
+/// [`CommandFactory`] which uses those two underlying traits to build the two
 /// fundamental functions `parse` which uses the `std::env::args_os` iterator,
 /// and `parse_from` which allows the consumer to supply the iterator (along
 /// with fallible options for each).
@@ -76,10 +76,10 @@ use std::ffi::OsString;
 /// }
 /// ```
 ///
-pub trait Parser: FromArgMatches + IntoApp + Sized {
+pub trait Parser: FromArgMatches + CommandFactory + Sized {
     /// Parse from `std::env::args_os()`, exit on error
     fn parse() -> Self {
-        let matches = <Self as IntoApp>::into_app().get_matches();
+        let matches = <Self as CommandFactory>::command().get_matches();
         let res =
             <Self as FromArgMatches>::from_arg_matches(&matches).map_err(format_error::<Self>);
         match res {
@@ -94,7 +94,7 @@ pub trait Parser: FromArgMatches + IntoApp + Sized {
 
     /// Parse from `std::env::args_os()`, return Err on error.
     fn try_parse() -> Result<Self, Error> {
-        let matches = <Self as IntoApp>::into_app().try_get_matches()?;
+        let matches = <Self as CommandFactory>::command().try_get_matches()?;
         <Self as FromArgMatches>::from_arg_matches(&matches).map_err(format_error::<Self>)
     }
 
@@ -104,7 +104,7 @@ pub trait Parser: FromArgMatches + IntoApp + Sized {
         I: IntoIterator<Item = T>,
         T: Into<OsString> + Clone,
     {
-        let matches = <Self as IntoApp>::into_app().get_matches_from(itr);
+        let matches = <Self as CommandFactory>::command().get_matches_from(itr);
         let res =
             <Self as FromArgMatches>::from_arg_matches(&matches).map_err(format_error::<Self>);
         match res {
@@ -123,7 +123,7 @@ pub trait Parser: FromArgMatches + IntoApp + Sized {
         I: IntoIterator<Item = T>,
         T: Into<OsString> + Clone,
     {
-        let matches = <Self as IntoApp>::into_app().try_get_matches_from(itr)?;
+        let matches = <Self as CommandFactory>::command().try_get_matches_from(itr)?;
         <Self as FromArgMatches>::from_arg_matches(&matches).map_err(format_error::<Self>)
     }
 
@@ -133,7 +133,7 @@ pub trait Parser: FromArgMatches + IntoApp + Sized {
         I: IntoIterator<Item = T>,
         T: Into<OsString> + Clone,
     {
-        let matches = <Self as IntoApp>::into_app_for_update().get_matches_from(itr);
+        let matches = <Self as CommandFactory>::command_for_update().get_matches_from(itr);
         let res = <Self as FromArgMatches>::update_from_arg_matches(self, &matches)
             .map_err(format_error::<Self>);
         if let Err(e) = res {
@@ -149,20 +149,20 @@ pub trait Parser: FromArgMatches + IntoApp + Sized {
         I: IntoIterator<Item = T>,
         T: Into<OsString> + Clone,
     {
-        let matches = <Self as IntoApp>::into_app_for_update().try_get_matches_from(itr)?;
+        let matches = <Self as CommandFactory>::command_for_update().try_get_matches_from(itr)?;
         <Self as FromArgMatches>::update_from_arg_matches(self, &matches)
             .map_err(format_error::<Self>)
     }
 
-    /// Deprecated, `StructOpt::clap` replaced with [`IntoCommand::into_app`] (derive as part of
+    /// Deprecated, `StructOpt::clap` replaced with [`IntoCommand::command`] (derive as part of
     /// [`Parser`])
     #[deprecated(
         since = "3.0.0",
-        note = "`StructOpt::clap` is replaced with `IntoCommand::into_app` (derived as part of `Parser`)"
+        note = "`StructOpt::clap` is replaced with `IntoCommand::command` (derived as part of `Parser`)"
     )]
     #[doc(hidden)]
     fn clap<'help>() -> Command<'help> {
-        <Self as IntoApp>::into_app()
+        <Self as CommandFactory>::command()
     }
 
     /// Deprecated, `StructOpt::from_clap` replaced with [`FromArgMatches::from_arg_matches`] (derive as part of
@@ -229,14 +229,29 @@ pub trait Parser: FromArgMatches + IntoApp + Sized {
 /// Create an [`Command`] relevant for a user-defined container.
 ///
 /// Derived as part of [`Parser`].
-pub trait IntoApp: Sized {
+pub trait CommandFactory: Sized {
     /// Build an [`Command`] that can instantiate `Self`.
     ///
     /// See [`FromArgMatches::from_arg_matches`] for instantiating `Self`.
+    fn command<'help>() -> Command<'help> {
+        #[allow(deprecated)]
+        Self::into_app()
+    }
+    /// Deprecated, replaced with `CommandFactory::command`
+    #[deprecated(since = "3.1.0", note = "Replaced with `CommandFactory::command")]
     fn into_app<'help>() -> Command<'help>;
     /// Build an [`Command`] that can update `self`.
     ///
     /// See [`FromArgMatches::update_from_arg_matches`] for updating `self`.
+    fn command_for_update<'help>() -> Command<'help> {
+        #[allow(deprecated)]
+        Self::into_app_for_update()
+    }
+    /// Deprecated, replaced with `CommandFactory::command_for_update`
+    #[deprecated(
+        since = "3.1.0",
+        note = "Replaced with `CommandFactory::command_for_update"
+    )]
     fn into_app_for_update<'help>() -> Command<'help>;
 }
 
@@ -315,13 +330,13 @@ pub trait FromArgMatches: Sized {
 pub trait Args: FromArgMatches + Sized {
     /// Append to [`Command`] so it can instantiate `Self`.
     ///
-    /// See also [`IntoApp`].
+    /// See also [`CommandFactory`].
     fn augment_args(cmd: Command<'_>) -> Command<'_>;
     /// Append to [`Command`] so it can update `self`.
     ///
     /// This is used to implement `#[clap(flatten)]`
     ///
-    /// See also [`IntoApp`].
+    /// See also [`CommandFactory`].
     fn augment_args_for_update(cmd: Command<'_>) -> Command<'_>;
 }
 
@@ -359,13 +374,13 @@ pub trait Args: FromArgMatches + Sized {
 pub trait Subcommand: FromArgMatches + Sized {
     /// Append to [`Command`] so it can instantiate `Self`.
     ///
-    /// See also [`IntoApp`].
+    /// See also [`CommandFactory`].
     fn augment_subcommands(cmd: Command<'_>) -> Command<'_>;
     /// Append to [`Command`] so it can update `self`.
     ///
     /// This is used to implement `#[clap(flatten)]`
     ///
-    /// See also [`IntoApp`].
+    /// See also [`CommandFactory`].
     fn augment_subcommands_for_update(cmd: Command<'_>) -> Command<'_>;
     /// Test whether `Self` can parse a specific subcommand
     fn has_subcommand(name: &str) -> bool;
@@ -451,12 +466,13 @@ impl<T: Parser> Parser for Box<T> {
     }
 }
 
-impl<T: IntoApp> IntoApp for Box<T> {
+#[allow(deprecated)]
+impl<T: CommandFactory> CommandFactory for Box<T> {
     fn into_app<'help>() -> Command<'help> {
-        <T as IntoApp>::into_app()
+        <T as CommandFactory>::into_app()
     }
     fn into_app_for_update<'help>() -> Command<'help> {
-        <T as IntoApp>::into_app_for_update()
+        <T as CommandFactory>::into_app_for_update()
     }
 }
 
@@ -490,7 +506,7 @@ impl<T: Subcommand> Subcommand for Box<T> {
     }
 }
 
-fn format_error<I: IntoApp>(err: crate::Error) -> crate::Error {
-    let mut cmd = I::into_app();
+fn format_error<I: CommandFactory>(err: crate::Error) -> crate::Error {
+    let mut cmd = I::command();
     err.format(&mut cmd)
 }
diff --git a/src/lib.rs b/src/lib.rs
index 6e4c3b8b..dd244e44 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -35,7 +35,7 @@ pub use crate::parse::{ArgMatches, Indices, OsValues, ValueSource, Values};
 #[cfg(feature = "color")]
 pub use crate::util::color::ColorChoice;
 
-pub use crate::derive::{ArgEnum, Args, FromArgMatches, IntoApp, Parser, Subcommand};
+pub use crate::derive::{ArgEnum, Args, CommandFactory, FromArgMatches, Parser, Subcommand};
 
 pub use crate::error::{ErrorKind, Result};
 
@@ -55,6 +55,10 @@ pub use yaml_rust::YamlLoader;
 #[doc(hidden)]
 pub use clap_derive::{self, *};
 
+/// Deprecated, replaced with [`CommandFactory`]
+#[deprecated(since = "3.0.0", note = "Replaced with `CommandFactory`")]
+#[doc(hidden)]
+pub use CommandFactory as IntoApp;
 /// Deprecated, replaced with [`Parser`]
 #[deprecated(since = "3.0.0", note = "Replaced with `Parser`")]
 #[doc(hidden)]


Test patch:
diff --git a/tests/derive/app_name.rs b/tests/derive/app_name.rs
index b21257aa..9e2f8d80 100644
--- a/tests/derive/app_name.rs
+++ b/tests/derive/app_name.rs
@@ -1,4 +1,4 @@
-use clap::IntoApp;
+use clap::CommandFactory;
 use clap::Parser;
 #[test]
 fn app_name_in_short_help_from_struct() {
@@ -7,7 +7,7 @@ fn app_name_in_short_help_from_struct() {
     struct MyApp {}
 
     let mut help = Vec::new();
-    MyApp::into_app().write_help(&mut help).unwrap();
+    MyApp::command().write_help(&mut help).unwrap();
     let help = String::from_utf8(help).unwrap();
 
     assert!(help.contains("my-cmd"));
@@ -20,7 +20,7 @@ fn app_name_in_long_help_from_struct() {
     struct MyApp {}
 
     let mut help = Vec::new();
-    MyApp::into_app().write_long_help(&mut help).unwrap();
+    MyApp::command().write_long_help(&mut help).unwrap();
     let help = String::from_utf8(help).unwrap();
 
     assert!(help.contains("my-cmd"));
@@ -33,7 +33,7 @@ fn app_name_in_short_help_from_enum() {
     enum MyApp {}
 
     let mut help = Vec::new();
-    MyApp::into_app().write_help(&mut help).unwrap();
+    MyApp::command().write_help(&mut help).unwrap();
     let help = String::from_utf8(help).unwrap();
 
     assert!(help.contains("my-cmd"));
@@ -46,7 +46,7 @@ fn app_name_in_long_help_from_enum() {
     enum MyApp {}
 
     let mut help = Vec::new();
-    MyApp::into_app().write_long_help(&mut help).unwrap();
+    MyApp::command().write_long_help(&mut help).unwrap();
     let help = String::from_utf8(help).unwrap();
 
     assert!(help.contains("my-cmd"));
@@ -58,7 +58,7 @@ fn app_name_in_short_version_from_struct() {
     #[clap(name = "my-cmd")]
     struct MyApp {}
 
-    let version = MyApp::into_app().render_version();
+    let version = MyApp::command().render_version();
 
     assert!(version.contains("my-cmd"));
 }
@@ -69,7 +69,7 @@ fn app_name_in_long_version_from_struct() {
     #[clap(name = "my-cmd")]
     struct MyApp {}
 
-    let version = MyApp::into_app().render_long_version();
+    let version = MyApp::command().render_long_version();
 
     assert!(version.contains("my-cmd"));
 }
@@ -80,7 +80,7 @@ fn app_name_in_short_version_from_enum() {
     #[clap(name = "my-cmd")]
     enum MyApp {}
 
-    let version = MyApp::into_app().render_version();
+    let version = MyApp::command().render_version();
 
     assert!(version.contains("my-cmd"));
 }
@@ -91,7 +91,7 @@ fn app_name_in_long_version_from_enum() {
     #[clap(name = "my-cmd")]
     enum MyApp {}
 
-    let version = MyApp::into_app().render_long_version();
+    let version = MyApp::command().render_long_version();
 
     assert!(version.contains("my-cmd"));
 }
diff --git a/tests/derive/arguments.rs b/tests/derive/arguments.rs
index 9de31f31..57c5866d 100644
--- a/tests/derive/arguments.rs
+++ b/tests/derive/arguments.rs
@@ -12,7 +12,7 @@
 // commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
 // MIT/Apache 2.0 license.
 
-use clap::IntoApp;
+use clap::CommandFactory;
 use clap::Parser;
 
 #[test]
@@ -52,7 +52,7 @@ fn auto_value_name() {
     }
 
     let mut help = Vec::new();
-    Opt::into_app().write_help(&mut help).unwrap();
+    Opt::command().write_help(&mut help).unwrap();
     let help = String::from_utf8(help).unwrap();
 
     assert!(help.contains("MY_SPECIAL_ARG"));
@@ -72,7 +72,7 @@ fn explicit_value_name() {
     }
 
     let mut help = Vec::new();
-    Opt::into_app().write_help(&mut help).unwrap();
+    Opt::command().write_help(&mut help).unwrap();
     let help = String::from_utf8(help).unwrap();
 
     assert!(help.contains("BROWNIE_POINTS"));
diff --git a/tests/derive/custom_string_parsers.rs b/tests/derive/custom_string_parsers.rs
index 2609a9d8..84279df3 100644
--- a/tests/derive/custom_string_parsers.rs
+++ b/tests/derive/custom_string_parsers.rs
@@ -144,7 +144,8 @@ fn update_every_custom_parser() {
         d: "D",
     };
 
-    opt.update_from(&["test", "-a=?", "-b=?", "-d=?"]);
+    opt.try_update_from(&["test", "-a=?", "-b=?", "-d=?"])
+        .unwrap();
 
     assert_eq!(
         NoOpOpt {
diff --git a/tests/derive/default_value.rs b/tests/derive/default_value.rs
index 94dbdaf1..db2b7838 100644
--- a/tests/derive/default_value.rs
+++ b/tests/derive/default_value.rs
@@ -1,4 +1,4 @@
-use clap::{IntoApp, Parser};
+use clap::{CommandFactory, Parser};
 
 use crate::utils;
 
@@ -53,5 +53,5 @@ fn detect_os_variant() {
         #[clap(default_value_os = ("123".as_ref()))]
         x: String,
     }
-    Options::into_app().debug_assert();
+    Options::command().debug_assert();
 }
diff --git a/tests/derive/doc_comments_help.rs b/tests/derive/doc_comments_help.rs
index 7ecee2f1..d5836c25 100644
--- a/tests/derive/doc_comments_help.rs
+++ b/tests/derive/doc_comments_help.rs
@@ -14,7 +14,7 @@
 
 use crate::utils;
 
-use clap::{ArgEnum, IntoApp, Parser};
+use clap::{ArgEnum, CommandFactory, Parser};
 
 #[test]
 fn doc_comments() {
@@ -232,7 +232,7 @@ fn doc_comment_about_handles_both_abouts() {
         Compress { output: String },
     }
 
-    let cmd = Opts::into_app();
+    let cmd = Opts::command();
     assert_eq!(cmd.get_about(), Some("Opts doc comment summary"));
     // clap will fallback to `about` on `None`.  The main care about is not providing a `Sub` doc
     // comment.
diff --git a/tests/derive/help.rs b/tests/derive/help.rs
index 1b1ce52f..4cd1d943 100644
--- a/tests/derive/help.rs
+++ b/tests/derive/help.rs
@@ -1,4 +1,4 @@
-use clap::{AppSettings, Args, IntoApp, Parser, Subcommand};
+use clap::{AppSettings, Args, CommandFactory, Parser, Subcommand};
 
 #[test]
 fn arg_help_heading_applied() {
@@ -12,7 +12,7 @@ fn arg_help_heading_applied() {
         no_section: u32,
     }
 
-    let cmd = CliOptions::into_app();
+    let cmd = CliOptions::command();
 
     let should_be_in_section_a = cmd
         .get_arguments()
@@ -40,7 +40,7 @@ fn app_help_heading_applied() {
         should_be_in_default_section: u32,
     }
 
-    let cmd = CliOptions::into_app();
+    let cmd = CliOptions::command();
 
     let should_be_in_section_a = cmd
         .get_arguments()
@@ -117,7 +117,7 @@ fn app_help_heading_flattened() {
         SubCOne { should_be_in_sub_c: u32 },
     }
 
-    let cmd = CliOptions::into_app();
+    let cmd = CliOptions::command();
 
     let should_be_in_section_a = cmd
         .get_arguments()
@@ -178,7 +178,7 @@ fn flatten_field_with_help_heading() {
         should_be_in_section_a: u32,
     }
 
-    let cmd = CliOptions::into_app();
+    let cmd = CliOptions::command();
 
     let should_be_in_section_a = cmd
         .get_arguments()
@@ -277,8 +277,8 @@ OPTIONS:
         option_b: Option<String>,
     }
 
-    use clap::IntoApp;
-    let mut cmd = Args::into_app();
+    use clap::CommandFactory;
+    let mut cmd = Args::command();
 
     let mut buffer: Vec<u8> = Default::default();
     cmd.write_help(&mut buffer).unwrap();
@@ -334,8 +334,8 @@ OPTIONS:
         option_b: Option<String>,
     }
 
-    use clap::IntoApp;
-    let mut cmd = Args::into_app();
+    use clap::CommandFactory;
+    let mut cmd = Args::command();
 
     let mut buffer: Vec<u8> = Default::default();
     cmd.write_help(&mut buffer).unwrap();
@@ -390,8 +390,8 @@ OPTIONS:
         option_b: Option<String>,
     }
 
-    use clap::IntoApp;
-    let mut cmd = Args::into_app();
+    use clap::CommandFactory;
+    let mut cmd = Args::command();
 
     let mut buffer: Vec<u8> = Default::default();
     cmd.write_help(&mut buffer).unwrap();
diff --git a/tests/derive/utils.rs b/tests/derive/utils.rs
index a9561003..6b649c3e 100644
--- a/tests/derive/utils.rs
+++ b/tests/derive/utils.rs
@@ -5,11 +5,13 @@
 // Accept and endure. Do not touch.
 #![allow(unused)]
 
-use clap::IntoApp;
+use clap::CommandFactory;
 
-pub fn get_help<T: IntoApp>() -> String {
+pub fn get_help<T: CommandFactory>() -> String {
     let mut output = Vec::new();
-    <T as IntoApp>::into_app().write_help(&mut output).unwrap();
+    <T as CommandFactory>::command()
+        .write_help(&mut output)
+        .unwrap();
     let output = String::from_utf8(output).unwrap();
 
     eprintln!("\n%%% HELP %%%:=====\n{}\n=====\n", output);
@@ -18,9 +20,9 @@ pub fn get_help<T: IntoApp>() -> String {
     output
 }
 
-pub fn get_long_help<T: IntoApp>() -> String {
+pub fn get_long_help<T: CommandFactory>() -> String {
     let mut output = Vec::new();
-    <T as IntoApp>::into_app()
+    <T as CommandFactory>::command()
         .write_long_help(&mut output)
         .unwrap();
     let output = String::from_utf8(output).unwrap();
@@ -31,9 +33,9 @@ pub fn get_long_help<T: IntoApp>() -> String {
     output
 }
 
-pub fn get_subcommand_long_help<T: IntoApp>(subcmd: &str) -> String {
+pub fn get_subcommand_long_help<T: CommandFactory>(subcmd: &str) -> String {
     let mut output = Vec::new();
-    <T as IntoApp>::into_app()
+    <T as CommandFactory>::command()
         .get_subcommands_mut()
         .find(|s| s.get_name() == subcmd)
         .unwrap()