`args_conflicts_with_subcommands` is not overriding `subcommand_required = true`
fooblinator opened this issue · comments
Discussed in #5353
Originally posted by fooblinator February 15, 2024
I have a flag ("--about") at the "top level", meaning as a child argument of the program's command. It's a bool so is optional. I don't need it to be required. I also have a subcommand at the same level, which points to an enum of subcommands, whose variants point to other enums (nested subcommands).
As a config option, I have "args_conflicts_with_subcommands" set to true. Also, I have "arg_required_else_help" set to false, so I can see the generated error, when I fail to provide a command name. The error and usage makes good sense, and when not providing a subcommand, this message makes good suggestions about what to try:
error: 'expenses' requires a subcommand but one was not provided
[subcommands: manage, track, help]Usage: expenses [OPTIONS]
expenses <COMMAND>For more information, try '--help'.
The above happens when my subcommand is configured to be required (through not configuring it as an Option<T>).
Question is: is there a way to have the functionality where:
- If you pass "--about" and NOT a subcommand, this is valid, and the program displays the about message.
- If you pass a subcommand (and its' nested subcommands/args), this is valid, and the program will execute that subcommand functionality.
- If you pass NOTHING, get the same error response you would get if the subcommand were required (like quoted above).
Here's some code I'm using:
[derive(Parser)]
#[command(about, version)]
#[command(
arg_required_else_help = false,
args_conflicts_with_subcommands = true,
)]
struct Cli {
/// Print about
#[arg(long, short)]
about: bool,
#[command(subcommand)]
commands: CliCmds, // or `commands: Option<CliCmds>,` ???
}
#[derive(Subcommand)]
enum CliCmds {
#[command(subcommand)]
Manage(CliManageCmds),
#[command(subcommand)]
Track(CliTrackCmds),
}
/// Manage expense definitions
#[derive(Subcommand)]
#[command(arg_required_else_help = false)]
enum CliManageCmds {
/// List existing expense definitions
List,
/// Search for existing expense definitions
Search,
/// Modify an existing expense definition
Modify,
/// Register a new expense definition
Register,
/// Archive an existing expense definition
Archive,
}
/// Track defined expenses
#[derive(Subcommand, Debug)]
#[command(arg_required_else_help = false)]
enum CliTrackCmds {
/// Mark an expense as staged to be paid
Staged,
/// Mark an expense as deferred (until a future pay period)
Deferred,
/// Mark an expense as paid (either fully or partially)
Paid,
}
In summary, when I make my top-level commands required ("commands: CliCmds"), I can't use the "--about" top-level flag. But when I make those subcommands optional ("command: Option<CliCmds>"), then I can use the flag, but the helpful error doesn't display (when neither "--about" nor a subcommand is passed).