Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

args_conflicts_with_subcommands is not overriding subcommand_required = true #5358

Open
fooblinator opened this issue Feb 16, 2024 Discussed in #5353 · 1 comment
Open
Labels
A-parsing Area: Parser's logic and needs it changed somehow. E-easy Call for participation: Experience needed to fix: Easy / not much M-breaking-change Meta: Implementing or merging this will introduce a breaking change.

Comments

@fooblinator
Copy link

fooblinator commented Feb 16, 2024

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:

  1. If you pass "--about" and NOT a subcommand, this is valid, and the program displays the about message.
  2. If you pass a subcommand (and its' nested subcommands/args), this is valid, and the program will execute that subcommand functionality.
  3. 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).

@epage epage added M-breaking-change Meta: Implementing or merging this will introduce a breaking change. A-parsing Area: Parser's logic and needs it changed somehow. labels Feb 19, 2024
@epage epage changed the title Optional flag at top-level conflicts with required top-level subcommands args_conflicts_with_subcommands is not overriding subcommand_required = true Feb 19, 2024
@epage
Copy link
Member

epage commented Feb 19, 2024

This is the other half of #3974 / #3940. We considered that a breaking change and, out of a preponderance of caution, I'm taking that as a default stance here as well.

@epage epage added the E-easy Call for participation: Experience needed to fix: Easy / not much label Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-parsing Area: Parser's logic and needs it changed somehow. E-easy Call for participation: Experience needed to fix: Easy / not much M-breaking-change Meta: Implementing or merging this will introduce a breaking change.
Projects
None yet
Development

No branches or pull requests

2 participants