-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Please complete the following tasks
- I have searched the discussions
- I have searched the open and rejected issues
Clap Version
4.5.20
Describe your use case
It's currently fairly cumbersome to alter the about
message for auto-generated help subcommands when using clap-derive
. Consider the following example scenario:
use clap::{command, CommandFactory, FromArgMatches, Parser, Subcommand};
#[derive(Parser)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Subcommand)]
pub enum Commands {
Subcmd,
}
To use the parser as-is, we can run something like:
fn main() {
let cli = Cli::parse();
match &cli.command { /* ... */ }
}
But if we'd like to customize the about
message for the generated help subcommand, we can no longer use the nice parse
methods on Cli
, and instead need to do something like:
fn main() -> Result<(), clap::Error> {
let mut cmd = Cli::command();
cmd.build(); // Need to build `cmd` to generate the `help` subcommand
let cmd = cmd.mut_subcommand("help", |help_cmd| {
help_cmd.about("A custom help message")
});
// Now we need to manually do what the `parse()` method would do, since we have a modified `Command`:
let mut matches = cmd.get_matches();
let cli = Cli::from_arg_matches(&mut matches)?;
match &cli.command { /* ... */ }
Ok(())
}
And for the sake of completeness, if we now run this with cargo run -- help
, we'd get:
Usage: clap_example [COMMAND]
Commands:
subcmd
help A custom help message
Options:
-h, --help Print help
Describe the solution you'd like
One way to streamline this would be to provide a build()
method on Command
which returns self
, so that we can directly call mut_subcommand
in the #[command()]
macro. For example, if Command
had something like:
#[cfg(feature = "derive")]
pub fn build_for_derive(mut self) -> Self {
self.build();
self
}
Then we could do the following:
#[derive(Parser)]
#[command(
build_for_derive(),
mut_subcommand("help", |subcmd| subcmd.about("A custom help message"),
)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
}
// ... `enum Commands` elided
fn main() {
// And now we can go back the straightforward setup:
let cli = Cli::parse();
match &cli.command { /* ... */ }
}
Note that trying to use build()
in place of the build_for_derive()
above doesn't work, as build()
mutates the Command
in-place and doesn't return anything, which breaks the Parser
derive macro.
Alternatives, if applicable
No response
Additional Context
No response