diff --git a/clap_builder/src/output/help_template.rs b/clap_builder/src/output/help_template.rs index 8c719043500..9fe7211b306 100644 --- a/clap_builder/src/output/help_template.rs +++ b/clap_builder/src/output/help_template.rs @@ -476,7 +476,7 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> { } } } - if flatten { + if subcmds && flatten { let mut cmd = self.cmd.clone(); cmd.build(); self.write_flat_subcommands(&cmd, &mut first); diff --git a/clap_builder/src/output/usage.rs b/clap_builder/src/output/usage.rs index 0b2ff3b93c3..d75b704ba74 100644 --- a/clap_builder/src/output/usage.rs +++ b/clap_builder/src/output/usage.rs @@ -103,7 +103,7 @@ impl<'cmd> Usage<'cmd> { debug!("Usage::write_help_usage"); use std::fmt::Write; - if self.cmd.is_flatten_help_set() { + if self.cmd.has_visible_subcommands() && self.cmd.is_flatten_help_set() { if !self.cmd.is_subcommand_required_set() || self.cmd.is_args_conflicts_with_subcommands_set() { @@ -113,7 +113,11 @@ impl<'cmd> Usage<'cmd> { } let mut cmd = self.cmd.clone(); cmd.build(); - for (i, sub) in cmd.get_subcommands().enumerate() { + for (i, sub) in cmd + .get_subcommands() + .filter(|c| !c.is_hide_set()) + .enumerate() + { if i != 0 { styled.trim_end(); let _ = write!(styled, "{}", USAGE_SEP); diff --git a/tests/builder/help.rs b/tests/builder/help.rs index 7ed6a2959fa..5f413145018 100644 --- a/tests/builder/help.rs +++ b/tests/builder/help.rs @@ -3308,6 +3308,81 @@ Print this message or the help of the given subcommand(s) utils::assert_output(cmd, "parent -h", EXPECTED, false); } +#[test] +fn flatten_single_hidden_command() { + static EXPECTED: &str = "\ +parent command + +Usage: parent [OPTIONS] + +Options: + --parent + -h, --help Print help +"; + let cmd = Command::new("parent") + .flatten_help(true) + .about("parent command") + .arg(Arg::new("parent").long("parent")) + .subcommand( + Command::new("child1") + .hide(true) + .about("child1 command") + .arg(Arg::new("child").long("child1")), + ); + utils::assert_output(cmd, "parent -h", EXPECTED, false); +} + +#[test] +fn flatten_hidden_command() { + static EXPECTED: &str = "\ +parent command + +Usage: parent [OPTIONS] + parent child1 [OPTIONS] + parent child2 [OPTIONS] + parent help [COMMAND]... + +Options: + --parent + -h, --help Print help + +parent child1: +child1 command + --child1 + -h, --help Print help + +parent child2: +child2 command + --child2 + -h, --help Print help + +parent help: +Print this message or the help of the given subcommand(s) + [COMMAND]... Print help for the subcommand(s) +"; + let cmd = Command::new("parent") + .flatten_help(true) + .about("parent command") + .arg(Arg::new("parent").long("parent")) + .subcommand( + Command::new("child1") + .about("child1 command") + .arg(Arg::new("child").long("child1")), + ) + .subcommand( + Command::new("child2") + .about("child2 command") + .arg(Arg::new("child").long("child2")), + ) + .subcommand( + Command::new("child3") + .hide(true) + .about("child3 command") + .arg(Arg::new("child").long("child3")), + ); + utils::assert_output(cmd, "parent -h", EXPECTED, false); +} + #[test] fn flatten_recursive() { static EXPECTED: &str = "\ @@ -3324,7 +3399,6 @@ Usage: parent [OPTIONS] parent child1 grandchild3 [OPTIONS] parent child1 help [COMMAND] parent child2 [OPTIONS] - parent child3 [OPTIONS] parent help [COMMAND]... Options: @@ -3379,11 +3453,6 @@ child2 command --child2 -h, --help Print help -parent child3: -child3 command - --child3 - -h, --help Print help - parent help: Print this message or the help of the given subcommand(s) [COMMAND]... Print help for the subcommand(s) @@ -3436,8 +3505,40 @@ Print this message or the help of the given subcommand(s) ) .subcommand( Command::new("child3") + .hide(true) .about("child3 command") - .arg(Arg::new("child").long("child3")), + .arg(Arg::new("child").long("child3")) + .subcommand( + Command::new("grandchild1") + .flatten_help(true) + .about("grandchild1 command") + .arg(Arg::new("grandchild").long("grandchild1")) + .subcommand( + Command::new("greatgrandchild1") + .about("greatgrandchild1 command") + .arg(Arg::new("greatgrandchild").long("greatgrandchild1")), + ) + .subcommand( + Command::new("greatgrandchild2") + .about("greatgrandchild2 command") + .arg(Arg::new("greatgrandchild").long("greatgrandchild2")), + ) + .subcommand( + Command::new("greatgrandchild3") + .about("greatgrandchild3 command") + .arg(Arg::new("greatgrandchild").long("greatgrandchild3")), + ), + ) + .subcommand( + Command::new("grandchild2") + .about("grandchild2 command") + .arg(Arg::new("grandchild").long("grandchild2")), + ) + .subcommand( + Command::new("grandchild3") + .about("grandchild3 command") + .arg(Arg::new("grandchild").long("grandchild3")), + ), ); utils::assert_output(cmd, "parent -h", EXPECTED, false); }