Control if Arg is hidden based on presence of another Arg
Please complete the following tasks
- [x] I have searched the discussions
- [x] I have searched the open and rejected issues
Clap Version
4.5.38
Describe your use case
I have a subcommand with 20+ flags. A small subset of these are common flags, while the rest are for advanced features.
Showing all the flags in --help is quite noisy; I would ideally like to have a --help where only the common flags are shown and a --help-all where all of the flags are shown. There doesn't seem to be a good mechanism to do this today?
The suggestion in #4687 is to use -h and --help, which doesn't work super great for me because the users of my CLI have all gotten accustomed to using --help. Further, it's not particularly ergonomic to write a custom --help flag for myself because my subcommands are defined in separate crates (where I have a main binary crate that depends on each subcommand crate), so there's no way for me to grab a CommandFactory to customize --help.
Describe the solution you'd like
I was thinking of something like hide_unless_present, along the lines of required_unless_present. Then you could write a subcommand like so:
#[derive(Args)]
struct Foo {
#[arg(long)]
common_flag: Option<String>,
#[arg(long, hide_unless_present = "help_all")]
advanced_flag: Option<String>,
/// Show advanced feature flags.
#[arg(long, action = ArgAction::HelpLong)]
help_all: (),
}
Alternatives, if applicable
No response
Additional Context
No response
The multi-crate aspect isn't too clear to me as to why you can't just do
#[derive(Args)]
#[command(disable_help_flag = true)]
struct Foo {
#[arg(long)]
common_flag: Option<String>,
#[arg(long, hide_short_help = true)]
advanced_flag: Option<String>,
/// Show basic feature flags.
#[arg(long, action = ArgAction::HelpShort)]
help: (),
/// Show advanced feature flags.
#[arg(long, action = ArgAction::HelpLong)]
help_all: (),
}
You might even be able to do
#[derive()]
#[command(disable_help_flag = true)]
struct Cli {
#[command(subcommand)]
command: Command,
/// Show basic feature flags.
#[arg(long, action = ArgAction::HelpShort, global = true)]
help: (),
/// Show advanced feature flags.
#[arg(long, action = ArgAction::HelpLong, global = true)]
help_all: (),
}
#[derive(Subcommand)]
enum Command {
Foo(Foo),
}
#[derive(Args)]
#[command(disable_help_flag = true)]
struct Foo {
#[arg(long)]
common_flag: Option<String>,
#[arg(long, hide_short_help = true)]
advanced_flag: Option<String>,
}
I was thinking of something like hide_unless_present, along the lines of required_unless_present. Then you could write a subcommand like so:
The problem with this is that the help action is activated immediately and is not aware of the full command line available.
The multi-crate aspect isn't too clear to me as to why you can't just do
Ah I brought up the multi-crate aspect because one way you could achieve this is by:
- Parse args (that include some
--help-allflag) - If
--help-allis used, then create a command factory, overridehidefor a set of arguments, then callprint_helpon that newCommand.
But this only works if you have access to the top-level CommandFactory.
#[arg(long, action = ArgAction::HelpLong, global = true)]
Hmm, suppose this works, though you're still limited to only having two "versions" of the help page. I.e. you could not have something like --help-feature-one and --help-feature-two.
The problem with this is that the help action is activated immediately and is not aware of the full command line available.
Yeah -- the solution I had in mind was to pass just the first argument that triggers HelpLong to write_help. If you wanted some "additive" functionality, that's where hide_unless_present_any comes in.
Hmm, suppose this works, though you're still limited to only having two "versions" of the help page. I.e. you could not have something like --help-feature-one and --help-feature-two.
Keep in mind, the original request was only for two forms of help. I'm ok with entertaining the idea of different flavors of help beyond short/long but it shouldn't be theoretical but a case we can concretely talk about and a clear example of why its important or generally applicable.
Generally when I've seen people want more than two topics, they tend to instead have "help topics" in a help subcommand. That is something we don't help with atm. If we went down the route of N flavors of help, I don't feel comfortable with hide_unless_present as I feel that over generalizes into a way that can be confusing for users approaching this as they are likely to assume that arguments after --help can affect --help.