clap icon indicating copy to clipboard operation
clap copied to clipboard

Unclear relationship between `global` and `required`

Open mlegner opened this issue 8 months ago • 1 comments

It is unclear whether an argument can be marked as global and required simultaneously. There used to be a note "Global arguments cannot be required." in the docs, which was removed in #1075. There still remains a debug assertion forbidding the combination.

If an argument is in fact both global and required, it seems that it is expected to be provided at all levels. Consider the following minimal example:

use clap::Parser;

#[derive(Parser)]
struct Cli {
    #[arg(long, global = true)]
    name: String,
    #[command(subcommand)]
    subcommand: Subcommand,
}

#[derive(Parser, Debug)]
enum Subcommand {
    Print,
}

fn main() {
    let cli = Cli::parse();
    println!("Name: {}", cli.name);
}

When running the debug build, this triggers the debug assertion:

$ cargo run -- print                        
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/test-clap print`

thread 'main' panicked at ~/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_builder-4.5.37/src/builder/debug_asserts.rs:255:9:
Command test-clap: Global arguments cannot be required.

        'name' is marked as both global and required

When running the release build, it requires the name at every level:

$ cargo run --release -- print --name test
    Finished `release` profile [optimized] target(s) in 0.06s
     Running `target/release/test-clap print --name test`
error: the following required arguments were not provided:
  --name <NAME>

Usage: test-clap --name <NAME> <COMMAND>

For more information, try '--help'.

$ cargo run --release -- --name test print
    Finished `release` profile [optimized] target(s) in 0.02s
     Running `target/release/test-clap --name test print`
error: the following required arguments were not provided:
  --name <NAME>

Usage: test-clap --name <NAME> print --name <NAME>

For more information, try '--help'.

$ cargo run --release -- --name test print --name test
    Finished `release` profile [optimized] target(s) in 0.01s
     Running `target/release/test-clap --name test print --name test`
Name: test

mlegner avatar Apr 24 '25 14:04 mlegner

Related issues:

  • #5020
  • #1546
  • #1204
  • #6049
  • #6160

epage avatar Apr 24 '25 14:04 epage