A full featured, fast Command Line Argument Parser for Rust

Overview

clap

Crates.io Crates.io License License Coverage Status Linux Build Status Windows Build Status

Command Line Argument Parser for Rust

It is a simple-to-use, efficient, and full-featured library for parsing command line arguments and subcommands when writing command line, console or terminal applications.

We are currently hard at work trying to release 3.0. We have a 3.0.0-beta.2 prerelease out but we do not give any guarantees that it's API is stable. We do not have a changelog yet which will be written down after we are sure about the API stability. We recommend users to not update to the prerelease version yet and to wait for the official 3.0.

If you're looking for the readme & examples for clap v2.33 - find it on github, crates.io, docs.rs.

  1. About
  2. FAQ
  3. Features
  4. Quick Example
    1. Using Derive Macros
    2. Using Builder Pattern
    3. Using YAML
    4. Using Macros
    5. Running it
  5. Try it!
    1. Pre-Built Test
    2. Build Your Own Binary
  6. Usage
    1. Optional Dependencies / Features
      1. Features enabled by default
      2. Opt-in features
    2. More Information
  7. Sponsors
  8. Contributing
    1. Compatibility Policy
      1. Minimum Supported Version of Rust (MSRV)
      2. Breaking Changes
  9. License
  10. Related Crates

About

clap is used to parse and validate the string of command line arguments provided by a user at runtime. You provide the list of valid possibilities, and clap handles the rest. This means you focus on your applications functionality, and less on the parsing and validating of arguments.

clap provides many things 'for free' (with no configuration) including the traditional version and help switches (or flags) along with associated messages. If you are using subcommands, clap will also auto-generate a help subcommand and separate associated help messages.

Once clap parses the user provided string of arguments, it returns the matches along with any applicable values. If the user made an error or typo, clap informs them with a friendly message and exits gracefully (or returns a Result type and allows you to perform any clean up prior to exit). Because of this, you can make reasonable assumptions in your code about the validity of the arguments prior to your applications main execution.

FAQ

For a full FAQ, see this

Features

Below are a few of the features which clap supports, full descriptions and usage can be found in the documentation and examples directory

  • Generate a CLI simply by defining a struct!
  • Auto-generated Help, Version, and Usage information
    • Can optionally be fully, or partially overridden if you want a custom help, version, or usage statements
  • Auto-generated completion scripts (Bash, Zsh, Fish, Elvish and PowerShell)
    • Using clap_generate
    • Even works through many multiple levels of subcommands
    • Works with options which only accept certain values
    • Works with subcommand aliases
  • Flags / Switches (i.e. bool fields)
    • Both short and long versions supported (i.e. -f and --flag respectively)
    • Supports combining short versions (i.e. -fBgoZ is the same as -f -B -g -o -Z)
    • Supports multiple occurrences (i.e. -vvv or -v -v -v)
  • Positional Arguments (i.e. those which are based off an index from the program name)
    • Supports multiple values (i.e. myprog <file>... such as myprog file1.txt file2.txt being two values for the same "file" argument)
    • Supports Specific Value Sets (See below)
    • Can set value parameters (such as the minimum number of values, the maximum number of values, or the exact number of values)
    • Can set custom validations on values to extend the argument parsing capability to truly custom domains
  • Option Arguments (i.e. those that take values)
    • Both short and long versions supported (i.e. -o value, -ovalue, -o=value and --option value or --option=value respectively)
    • Supports multiple values (i.e. -o <val1> -o <val2> or -o <val1> <val2>)
    • Supports delimited values (i.e. -o=val1,val2,val3, can also change the delimiter)
    • Supports Specific Value Sets (See below)
    • Supports named values so that the usage/help info appears as -o <FILE> <INTERFACE> etc. for when you require specific multiple values
    • Can set value parameters (such as the minimum number of values, the maximum number of values, or the exact number of values)
    • Can set custom validations on values to extend the argument parsing capability to truly custom domains
  • Sub-Commands (i.e. git add <file> where add is a sub-command of git)
    • Support their own sub-arguments, and sub-sub-commands independent of the parent
    • Get their own auto-generated Help, Version, and Usage independent of parent
  • Support for building CLIs from YAML - This keeps your Rust source nice and tidy and makes supporting localized translation very simple!
  • Requirement Rules: Arguments can define the following types of requirement rules
    • Can be required by default
    • Can be required only if certain arguments are present
    • Can require other arguments to be present
    • Can be required only if certain values of other arguments are used
  • Confliction Rules: Arguments can optionally define the following types of exclusion rules
    • Can be disallowed when certain arguments are present
    • Can disallow use of other arguments when present
  • Groups: Arguments can be made part of a group
    • Fully compatible with other relational rules (requirements, conflicts, and overrides) which allows things like requiring the use of any arg in a group, or denying the use of an entire group conditionally
  • Specific Value Sets: Positional or Option Arguments can define a specific set of allowed values (i.e. imagine a --mode option which may only have one of two values fast or slow such as --mode fast or --mode slow)
  • Default Values
    • Also supports conditional default values (i.e. a default which only applies if specific arguments are used, or specific values of those arguments)
  • Automatic Version from Cargo.toml: clap is fully compatible with Rust's env!() macro for automatically setting the version of your application to the version in your Cargo.toml. See 09_auto_version example for how to do this (Thanks to jhelwig for pointing this out)
  • Typed Values: You can use several convenience macros provided by clap to get typed values (i.e. i32, u8, etc.) from positional or option arguments so long as the type you request implements std::str::FromStr See the 12_typed_values example. You can also use claps arg_enum! macro to create an enum with variants that automatically implement std::str::FromStr. See 13_enum_values example for details
  • Suggestions: Suggests corrections when the user enters a typo. For example, if you defined a --myoption argument, and the user mistakenly typed --moyption (notice y and o transposed), they would receive a Did you mean '--myoption'? error and exit gracefully. This also works for subcommands and flags. (Thanks to Byron for the implementation) (This feature can optionally be disabled, see 'Optional Dependencies / Features')
  • Colorized Errors (Non Windows OS only): Error message are printed in colored text (this feature can optionally be disabled, see 'Optional Dependencies / Features').
  • Global Arguments: Arguments can optionally be defined once, and be available to all child subcommands. These values will also be propagated up/down throughout all subcommands.
  • Custom Validations: You can define a function to use as a validator of argument values. Imagine defining a function to validate IP addresses, or fail parsing upon error. This means your application logic can be solely focused on using values.
  • POSIX Compatible Conflicts/Overrides - In POSIX args can be conflicting, but not fail parsing because whichever arg comes last "wins" so to speak. This allows things such as aliases (i.e. alias ls='ls -l' but then using ls -C in your terminal which ends up passing ls -l -C as the final arguments. Since -l and -C aren't compatible, this effectively runs ls -C in clap if you choose...clap also supports hard conflicts that fail parsing). (Thanks to Vinatorul!)
  • Supports the Unix -- meaning, only positional arguments follow

Quick Example

The following examples show a quick example of some of the very basic functionality of clap. For more advanced usage, such as requirements, conflicts, groups, multiple values and occurrences see the documentation, examples directory of this repository.

NOTE: All of these examples are functionally the same, but show different styles in which to use clap. These different styles are purely a matter of personal preference.

Add clap to your Cargo.toml

[dependencies]
clap = "3.0.0-beta.2"

Using Derive Macros

The first example shows the simplest way to use clap, by defining a struct. If you're familiar with the structopt crate you're in luck, it's the same! (In fact it's the exact same code running under the covers!)

// (Full example with detailed comments in examples/01d_quick_example.rs)
//
// This example demonstrates clap's full 'custom derive' style of creating arguments which is the
// simplest method of use, but sacrifices some flexibility.
use clap::Clap;

/// This doc string acts as a help message when the user runs '--help'
/// as do all doc strings on fields
#[derive(Clap)]
#[clap(version = "1.0", author = "Kevin K. <[email protected]>")]
struct Opts {
    /// Sets a custom config file. Could have been an Option<T> with no default too
    #[clap(short, long, default_value = "default.conf")]
    config: String,
    /// Some input. Because this isn't an Option<T> it's required to be used
    input: String,
    /// A level of verbosity, and can be used multiple times
    #[clap(short, long, parse(from_occurrences))]
    verbose: i32,
    #[clap(subcommand)]
    subcmd: SubCommand,
}

#[derive(Clap)]
enum SubCommand {
    #[clap(version = "1.3", author = "Someone E. <[email protected]>")]
    Test(Test),
}

/// A subcommand for controlling testing
#[derive(Clap)]
struct Test {
    /// Print debug info
    #[clap(short)]
    debug: bool
}

fn main() {
    let opts: Opts = Opts::parse();

    // Gets a value for config if supplied by user, or defaults to "default.conf"
    println!("Value for config: {}", opts.config);
    println!("Using input file: {}", opts.input);

    // Vary the output based on how many times the user used the "verbose" flag
    // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
    match opts.verbose {
        0 => println!("No verbose info"),
        1 => println!("Some verbose info"),
        2 => println!("Tons of verbose info"),
        3 | _ => println!("Don't be crazy"),
    }

    // You can handle information about subcommands by requesting their matches by name
    // (as below), requesting just the name used, or both at the same time
    match opts.subcmd {
        SubCommand::Test(t) => {
            if t.debug {
                println!("Printing debug info...");
            } else {
                println!("Printing normally...");
            }
        }
    }

    // more program logic goes here...
}

Using Builder Pattern

This second method shows a method using the 'Builder Pattern' which allows more advanced configuration options (not shown in this small example), or even dynamically generating arguments when desired. The downside is it's more verbose.

// (Full example with detailed comments in examples/01b_quick_example.rs)
//
// This example demonstrates clap's "builder pattern" method of creating arguments
// which the most flexible, but also most verbose.
use clap::{Arg, App};

fn main() {
    let matches = App::new("My Super Program")
        .version("1.0")
        .author("Kevin K. <[email protected]>")
        .about("Does awesome things")
        .arg(Arg::new("config")
            .short('c')
            .long("config")
            .value_name("FILE")
            .about("Sets a custom config file")
            .takes_value(true))
        .arg(Arg::new("INPUT")
            .about("Sets the input file to use")
            .required(true)
            .index(1))
        .arg(Arg::new("v")
            .short('v')
            .multiple(true)
            .about("Sets the level of verbosity"))
        .subcommand(App::new("test")
            .about("controls testing features")
            .version("1.3")
            .author("Someone E. <[email protected]>")
            .arg(Arg::new("debug")
                .short('d')
                .about("print debug information verbosely")))
        .get_matches();

    // You can check the value provided by positional arguments, or option arguments
    if let Some(i) = matches.value_of("INPUT") {
        println!("Value for input: {}", i);
    }

    if let Some(c) = matches.value_of("config") {
        println!("Value for config: {}", c);
    }

    // You can see how many times a particular flag or argument occurred
    // Note, only flags can have multiple occurrences
    match matches.occurrences_of("v") {
        0 => println!("Verbose mode is off"),
        1 => println!("Verbose mode is kind of on"),
        2 => println!("Verbose mode is on"),
        3 | _ => println!("Don't be crazy"),
    }

    // You can check for the existence of subcommands, and if found use their
    // matches just as you would the top level app
    if let Some(ref matches) = matches.subcommand_matches("test") {
        // "$ myapp test" was run
        if matches.is_present("debug") {
            // "$ myapp test -d" was run
            println!("Printing debug info...");
        } else {
            println!("Printing normally...");
        }
    }

    // Continued program logic goes here...
}

The next example shows a far less verbose method, but sacrifices some of the advanced configuration options (not shown in this small example). This method also takes a very minor runtime penalty.

// (Full example with detailed comments in examples/01a_quick_example.rs)
//
// This example demonstrates clap's "usage strings" method of creating arguments
// which is less verbose
use clap::App;

fn main() {
    let matches = App::new("myapp")
        .version("1.0")
        .author("Kevin K. <[email protected]>")
        .about("Does awesome things")
        .arg("-c, --config=[FILE] 'Sets a custom config file'")
        .arg("<INPUT>              'Sets the input file to use'")
        .arg("-v...                'Sets the level of verbosity'")
        .subcommand(App::new("test")
            .about("controls testing features")
            .version("1.3")
            .author("Someone E. <[email protected]>")
            .arg("-d, --debug 'Print debug information'"))
        .get_matches();

    // Same as previous example...
}

Using YAML

This third method shows how you can use a YAML file to build your CLI and keep your Rust source tidy or support multiple localized translations by having different YAML files for each localization.

First, create the cli.yaml file to hold your CLI options, but it could be called anything we like:

name: myapp
version: "1.0"
author: Kevin K. <[email protected]>
about: Does awesome things
args:
    - config:
        short: c
        long: config
        value_name: FILE
        about: Sets a custom config file
        takes_value: true
    - INPUT:
        about: Sets the input file to use
        required: true
        index: 1
    - verbose:
        short: v
        multiple: true
        about: Sets the level of verbosity
subcommands:
    - test:
        about: controls testing features
        version: "1.3"
        author: Someone E. <[email protected]>
        args:
            - debug:
                short: d
                about: print debug information

Since this feature requires additional dependencies that not everyone may want, it is not compiled in by default and we need to enable a feature flag in Cargo.toml:

Simply add the yaml feature flag to your Cargo.toml.

[dependencies]
clap = { version = "3.0.0-beta.2", features = ["yaml"] }

Finally we create our main.rs file just like we would have with the previous two examples:

// (Full example with detailed comments in examples/17_yaml.rs)
//
// This example demonstrates clap's building from YAML style of creating arguments which is far
// more clean, but takes a very small performance hit compared to the other two methods.
use clap::{App, load_yaml};

fn main() {
    // The YAML file is found relative to the current file, similar to how modules are found
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from(yaml).get_matches();

    // Same as previous examples...
}

Using Macros

Finally there is a macro version, which is like a hybrid approach offering the speed of the builder pattern (the first example), but without all the verbosity.

use clap::clap_app;

fn main() {
    let matches = clap_app!(myapp =>
        (version: "1.0")
        (author: "Kevin K. <[email protected]>")
        (about: "Does awesome things")
        (@arg CONFIG: -c --config +takes_value "Sets a custom config file")
        (@arg INPUT: +required "Sets the input file to use")
        (@arg verbose: -v --verbose "Print test information verbosely")
        (@subcommand test =>
            (about: "controls testing features")
            (version: "1.3")
            (author: "Someone E. <[email protected]>")
            (@arg debug: -d ... "Sets the level of debugging information")
        )
    ).get_matches();

    // Same as previous examples...
}

Running it

If you were to compile any of the above programs and run them with the flag --help or -h (or help subcommand, since we defined test as a subcommand) the following would be output (except the first example where the help message sort of explains the Rust code).

$ myprog --help
My Super Program 1.0
Kevin K. <[email protected]>
Does awesome things

ARGS:
    INPUT    The input file to use

USAGE:
    MyApp [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -v               Sets the level of verbosity
    -V, --version    Prints version information

OPTIONS:
    -c, --config <FILE>    Sets a custom config file

SUBCOMMANDS:
    help    Prints this message or the help of the given subcommand(s)
    test    Controls testing features

NOTE: You could also run myapp test --help or myapp help test to see the help message for the test subcommand.

Try it!

Pre-Built Test

To try out the pre-built examples, use the following steps:

  • Clone the repository $ git clone https://github.com/clap-rs/clap && cd clap/
  • Compile the example $ cargo build --example <EXAMPLE>
  • Run the help info $ ./target/debug/examples/<EXAMPLE> --help
  • Play with the arguments!
  • You can also do a onetime run via $ cargo run --example <EXAMPLE> -- [args to example]

Build Your Own Binary

To test out clap's default auto-generated help/version follow these steps:

  • Create a new cargo project $ cargo new fake --bin && cd fake
  • Write your program as described in the quick example section.
  • Build your program $ cargo build --release
  • Run with help or version $ ./target/release/fake --help or $ ./target/release/fake --version

Usage

For full usage, add clap as a dependency in your Cargo.toml to use from crates.io:

[dependencies]
clap = "3.0.0-beta.2"

Define a list of valid arguments for your program (see the documentation or examples directory of this repo)

Then run cargo build or cargo update && cargo build for your project.

Optional Dependencies / Features

Features enabled by default

  • derive: Enables the custom derive (i.e. #[derive(Clap)]). Without this you must use one of the other methods of creating a clap CLI listed above
  • suggestions: Turns on the Did you mean '--myoption'? feature for when users make typos. (builds dependency strsim)
  • color: Turns on colored error messages. You still have to turn on colored help by setting AppSettings::ColoredHelp. (builds dependency termcolor)

To disable these, add this to your Cargo.toml:

[dependencies.clap]
version = "3.0.0-beta.2"
default-features = false

You can also selectively enable only the features you'd like to include, by adding:

[dependencies.clap]
version = "3.0.0-beta.2"
default-features = false

# Cherry-pick the features you'd like to use
features = [ "suggestions", "color" ]

Opt-in features

  • "wrap_help": Turns on the help text wrapping feature, based on the terminal size. (builds dependency term-size)
  • "yaml": Enables building CLIs from YAML documents. (builds dependency yaml-rust)
  • "regex": Enables regex validators. (builds dependency regex)
  • "unstable": Enables unstable clap features that may change from release to release

More Information

You can find complete documentation on the docs.rs for this project.

You can also find usage examples in the examples directory of this repo.

Sponsors

Gold

Silver

Bronze

Backer

Contributing

Details on how to contribute can be found in the CONTRIBUTING.md file.

Compatibility Policy

Because clap takes SemVer and compatibility seriously, this is the official policy regarding breaking changes and minimum required versions of Rust.

clap will pin the minimum required version of Rust to the CI builds. Bumping the minimum version of Rust is considered a minor breaking change, meaning at a minimum the minor version of clap will be bumped.

In order to keep from being surprised of breaking changes, it is highly recommended to use the ~major.minor.patch style in your Cargo.toml only if you wish to target a version of Rust that is older than current stable minus two releases:

[dependencies]
clap = "~3.0.0-beta.2"

This will cause only the patch version to be updated upon a cargo update call, and therefore cannot break due to new features, or bumped minimum versions of Rust.

Minimum Supported Version of Rust (MSRV)

clap will officially support current stable Rust, minus two releases, but may work with prior releases as well. For example, current stable Rust at the time of this writing is 1.38.0, meaning clap is guaranteed to compile with 1.36.0 and beyond.

At the 1.39.0 stable release, clap will be guaranteed to compile with 1.37.0 and beyond, etc.

The following is a list of the minimum required version of Rust to compile clap by our MAJOR.MINOR version number:

clap MSRV
>=3.0 1.46.0
>=2.21 1.24.0
>=2.2 1.12.0
>=2.1 1.6.0
>=1.5 1.4.0
>=1.4 1.2.0
>=1.2 1.1.0
>=1.0 1.0.0

Breaking Changes

clap takes a similar policy to Rust and will bump the major version number upon breaking changes with only the following exceptions:

  • The breaking change is to fix a security concern
  • The breaking change is to be fixing a bug (i.e. relying on a bug as a feature)
  • The breaking change is a feature isn't used in the wild, or all users of said feature have given approval prior to the change

License

clap is distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See the LICENSE-APACHE and LICENSE-MIT files in this repository for more information.

Related Crates

There are several excellent crates which can be used with clap, I recommend checking them all out! If you've got a crate that would be a good fit to be used with clap open an issue and let me know, I'd love to add it!

  • assert_cmd - This crate allows you test your CLIs in a very intuitive and functional way!
Comments
  • RFC: Clap, from scratch re-write and redesign discussion

    RFC: Clap, from scratch re-write and redesign discussion

    [Drafting; @kbknapp @sru please feel free to update this OP as you see fit. Please "create a lock" by posting a comment saying that you're editing - and then delete when done]

    From: https://github.com/kbknapp/clap-rs/issues/259#issuecomment-143956337

    • [x] List all current clap features and capabilities in the OP (EDIT: This is already mostly done, but not quite complete. There are a few features missing, or some that should be broken down into further sub-sections. EDIT 2: Also, I'm speaking more about separating current features, from proposed features, from implementation details...currently it's all mixed into one list)
    • [ ] Determine which of those capabilities will be changed (i.e. implemented but in a slightly different manner from the clap consumer standpoint...breaking changes)
    • [ ] Implement all current capabilities in clap 2.x tracked by individual 2.x issues with this issue being the overarching 2.x discussion forum and overall tracking issue
    • [ ] Determine which new features will be present in 2.x (i.e. custom Matches struct allowing things like matches.some_arg fields instead of the current matches.value_of("some_arg"))
    • [ ] Implement all new features in individual 2.x tracking issues, again with this issue being the overarching 2.x discussion forum
    • [ ] Test / Bench the 2.x branch to ensure we didn't lose ground
    • [ ] Once all features / bugs / benches have been worked from the 2.x branch we'll ensure docs are good to go and release

    Current (ripped from the README) feature

    • Auto-generated Help, Version, and Usage information
    • Flags
      • Short version (i.e. -f)
      • Long version (i.e. --flag)
      • Combining short versions (i.e. -fBgoZ is the same as -f -B -g -o -Z)
      • Multiple occurrences (i.e. -vvv or -v -v -v)
    • Positional Arguments (i.e. those which are based off an index from the program name)
      • Multiple values (i.e. myprog <file>...)
      • Supports the unix -- meaning, only positional arguments follow
      • Optionally sets value parameters
        • Minimum values
        • Maximum values
        • Exact number of values
    • Option Arguments (i.e. those that take values as options)
      • Short version (i.e. -o value)
      • Long version
        • --option value
        • --option=value
      • Multiple values
      • Named values
      • Value parameters
        • Minimum values
        • Maximum values
        • Exact number of values
    • Sub-Commands (i.e. git add <file> where add is a sub-command of git)
      • Their own sub-arguments, and sub-sub-commands independent of the parent
      • Get their own auto-generated Help, Version, and Usage independent of parent
    • Requirement Rules
      • Required by default
      • Required only if certain arguments are present
      • Can require other arguments to be present
    • Exclusion/Confliction Rules
      • Can be disallowed when certain arguments are present
      • Can disallow use of other arguments when present
    • Groups
      • Fully compatible with other relational rules (requirements and exclusions) which allows things like requiring the use of a group, or denying the use of a group conditionally
    • Specific Value Sets
      • For positional
      • For option
    • Default Values: Although not specifically provided by clap you can achieve this exact functionality from Rust's Option<&str>.unwrap_or("some default") method (or Result<T,String>.unwrap_or(T) when using typed values)
    • Automatic Version from Cargo.toml
    • Typed Values
    • Suggestions
    • Colorized (Red) Errors (Non Windows OS only)
    • Global Arguments
    • Custom Validations
    • POSIX Compatible Conflicts
    • Support for building CLIs from YAML

    Current Implementation Details

    (Something about the current design that needs attention)

    Proposed

    • [x] Flags
      • [x] Short version (i.e. -f)
      • [x] Long version (i.e. --flag)
      • [x] Combining short versions (i.e. -fBgoZ is the same as -f -B -g -o -Z)
      • [x] Multiple occurrences (i.e. -vvv or -v -v -v)
    • [ ] Positional Arguments (i.e. those which are based off an index from the program name)
      • [x] Multiple values (i.e. myprog <file>...)
      • [x] Supports the unix -- meaning, only positional arguments follow
      • [x] Optionally sets value parameters
        • [ ] Minimum values (needs post parser validation test)
        • [x] Maximum values
        • [x] Exact number of values
    • [ ] Option Arguments (i.e. those that take values as options)
      • [x] Short version (i.e. -o value)
      • [x] Long version
        • [x] --option value
        • [x] --option=value
      • [x] Multiple values
        • [x] ~~-o value -o other_value abbreviated to -o value other_value~~
          • [x] Instead abbreviated to -oo value other_value. The one instance of -o is too easily problematic.
        • [x] --option=val1,val2,val3
      • [x] Named values
      • [x] Value parameters
        • [ ] Minimum values (needs post parser validation test)
        • [x] Maximum values
        • [x] Exact number of values
    • [x] Specific Value Sets (possible values?)
      • [x] For positional
      • [x] For option
    • [ ] Sub-Commands (i.e. git add <file> where add is a sub-command of git)
      • [ ] Their own sub-arguments, and sub-sub-commands independent of the parent
      • [ ] Get their own auto-generated Help, Version, and Usage independent of parent
    • [ ] Requirement Rules
      • [x] ~~Required by default~~ Required through consumer decision. No default. Macro uses [] for optional and <> for required.
      • [ ] Required only if certain arguments are present
      • [ ] Can require other arguments to be present
    • [ ] Exclusion/Confliction Rules
      • [ ] Can be disallowed when certain arguments are present
      • [ ] Can disallow use of other arguments when present
    • [ ] Groups
      • [ ] Fully compatible with other relational rules (requirements and exclusions) which allows things like requiring the use of a group, or denying the use of a group conditionally
    • [ ] Global Arguments
    • [ ] Default Values
    • [ ] Automatic Version from Cargo.toml
    • [ ] Suggestions
    • [ ] Custom Validations
      • [x] Partial
    • [ ] Auto-generated Help, Version, and Usage information
    • [ ] Support for building CLIs from YAML
    • [ ] Typed Values
    • [ ] POSIX Compatible Conflicts
    • [ ] Colorized (Red) Errors (Non Windows OS only [why not, it has colors too?])

    Proposed Implementation Details

    RFCs

    Naming change Settings

    C-enhancement M-breaking-change A-builder A-parsing 
    opened by WildCryptoFox 85
  • Auto-generate manpage, help docs, etc.

    Auto-generate manpage, help docs, etc.

    Maintainer notes:

    • Blocked on https://github.com/clap-rs/clap/issues/2914 for decoupling help information gathering from formatting
    • help2man can be a source of inspiration for how to integrate this into a users process

    I'd love to have support to generate a manpage. This would use a mechanism and infrastructure similar to #376. Additional functions to override or augment portions of the generated manpage could come later, but I think with relatively few additions this could become an incredibly useful mechanism.

    • The manpage title should default to the bin_name value.
    • The section should default to 1.
    • The NAME section should default to bin_name \- about, where about is the string set by .about.
    • The SYNOPSIS section should contain the usage strings for the command and every subcommand.
    • The DESCRIPTION section would need some new paragraph-style information provided (also usable as a more structured .before_help).
    • The "OPTIONS" section should document the flags and args for the top-level command.
    • If the command has subcommands, a "SUBCOMMANDS" section should document each subcommand in a sub-section.
    • The AUTHORS section should contain the author information, if provided.
    • The SEE ALSO section would need some new mechanism to populate it.

    I'd be happy to help with manpage markup, once I see the details of the mechanism used in #376.

    C-enhancement A-help S-blocked 
    opened by joshtriplett 81
  • Re-license under the MIT/Apache 2.0

    Re-license under the MIT/Apache 2.0

    Note from @kbknapp

    Although I'm not a huge fan of dual licensing, I do see a big benefit in following the Rust trend here, and being compatible with that ecosystem.

    Also please note this was not part of the mass auto-generated issues. I opened this issue because I think it's a good idea for this project. I did however copy/paste the verbiage from the auto-generated issues.

    • Kevin

    TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that license is good for interoperation. The MIT license as an add-on can be nice for GPLv2 projects to use your code.

    Why?

    The MIT license requires reproducing countless copies of the same copyright header with different names in the copyright field, for every MIT library in use. The Apache license does not have this drawback. However, this is not the primary motivation for me creating these issues. The Apache license also has protections from patent trolls and an explicit contribution licensing clause. However, the Apache license is incompatible with GPLv2. This is why Rust is dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for GPLv2 compat), and doing so would be wise for this project. This also makes this crate suitable for inclusion and unrestricted sharing in the Rust standard distribution and other projects using dual MIT/Apache, such as my personal ulterior motive, the Robigalia project.

    Some ask, "Does this really apply to binary redistributions? Does MIT really require reproducing the whole thing?" I'm not a lawyer, and I can't give legal advice, but some Google Android apps include open source attributions using this interpretation. Others also agree with it. But, again, the copyright notice redistribution is not the primary motivation for the dual-licensing. It's stronger protections to licensees and better interoperation with the wider Rust ecosystem.

    How?

    To do this, get explicit approval from each contributor of copyrightable work (as not all contributions qualify for copyright, due to not being a "creative work", e.g. a typo fix) and then add the following to your README:

    ## License
    
    Licensed under either of
    
     * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
     * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
    
    at your option.
    
    ### Contribution
    
    Unless you explicitly state otherwise, any contribution intentionally submitted
    for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
    additional terms or conditions.
    

    and in your license headers, if you have them, use the following boilerplate (based on that used in Rust):

    // Copyright 2016 clap-rs Developers
    //
    // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
    // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
    // http://opensource.org/licenses/MIT>, at your option. This file may not be
    // copied, modified, or distributed except according to those terms.
    

    It's commonly asked whether license headers are required. I'm not comfortable making an official recommendation either way, but the Apache license recommends it in their appendix on how to use the license.

    Be sure to add the relevant LICENSE-{MIT,APACHE} files. You can copy these from the Rust repo for a plain-text version.

    And don't forget to update the license metadata in your Cargo.toml to:

    license = "MIT OR Apache-2.0"
    

    I'll be going through projects which agree to be relicensed and have approval by the necessary contributors and doing this changes, so feel free to leave the heavy lifting to me!

    Contributor checkoff

    All contributors with more than 100 lines of changes need to agree to relicensing for this to take pace. Please comment with :

    I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.
    

    Or, if you're a contributor, you can check the box in this repo next to your name. My scripts will pick this exact phrase up and check your checkbox, but I'll come through and manually review this issue later as well.

    • [x] @kbknapp
    • [x] @Arnavion
    • [x] @afiune
    • [x] @alex-gulyas
    • [x] @AluisioASG
    • [x] @archer884
    • [x] @Bilalh
    • [x] @birkenfeld
    • [x] @bradurani
    • [x] @brennie
    • [x] @brianp
    • [x] @bluejekyll
    • [x] @Byron
    • [x] @cstorey
    • [x] @cite-reader
    • [x] @crazymerlyn
    • [x] @davidszotten
    • [x] @dguo
    • [x] @grossws
    • [x] @Geogi
    • [x] @gohyda
    • [x] @hgrecco
    • [x] @huonw
    • [x] @hoodie
    • [x] @idmit
    • [x] @iliekturtles
    • [ ] @james-darkfox
    • [x] @jespino
    • [x] @jimmycuadra
    • [x] @japaric
    • [x] @joshtriplett
    • [x] @Keats
    • [x] @little-dude
    • [x] @malbarbo
    • [x] @mgeisler
    • [x] @messense
    • [x] @N-006
    • [x] @nabijaczleweli
    • [x] @nagya11
    • [ ] @nateozem
    • [x] @Nemo157
    • [x] @nelsonjchen
    • [x] @nicompte
    • [x] @nvzqz
    • [x] @ogham
    • [x] @panicbit
    • [x] @peppsac
    • [x] @psyomn
    • [x] @rnelson
    • [x] @rtaycher
    • [ ] @segevfiner
    • [x] @SirVer
    • [x] @sru
    • [x] @SShrike
    • [x] @starkat99
    • [x] @swatteau
    • [ ] @tanakh
    • [x] @th4t
    • [x] @tormol
    • [x] @untitaker
    • [x] @Vinatorul
    • [ ] @wdv4758h
    • [x] @willmurphyscode

    Edit 2018-02-15: Updated list of contributors meeting requirements as of today. I also left names of those with less than 100 lines of changes that have already signed off.

    A-docs 
    opened by kbknapp 66
  • Iterating over `ArgMatches`

    Iterating over `ArgMatches`

    Maintainer's notes

    • This is blocked on https://github.com/clap-rs/clap/issues/1041 / https://github.com/clap-rs/clap/issues/2150 where we move away from opaque, non-public Ids for arguments to something the user can programmatically act on

    Hi, I am using Clap in a little side project and I would like to suggest a minor feature. I am ready to implement it myself and send a PR if needed, I just need a few pointers. The feature at hand is an ordered iterator over ArgMatches: as far as my understanding goes, Clap doesn't allow to freely iterate over the parsed arguments. What if my application APIs are dependent upon the order of the arguments? GNU find comes to my mind. Calling index_of for every argument can be expensive if you have a lot of them.

    If this feature were to be implemented, what would the return type and name of the method be?

    C-enhancement M-breaking-change A-parsing E-medium 
    opened by neysofu 54
  • Macros to simplify builders

    Macros to simplify builders

    Macros can be used to make builders easier to manage, without adding any performance overheads for parsing strings at runtime, or handling YAML at compile time.

    Notes

    This macro is defined as an S-expression. What this means is that it can both take many arguments and parse complicated usage-string-like syntax (like @arg foo: -s --long <required_arg> [optional_arg] ... conflicts[some_arg] requires[other_arg] {validator_function} "Foobar!") without reaching the recursion limit of 64.

    @subcommand and @group allow for visual hierarchy to understand relationships between arguments, commands, and other related meta.

    Updated sample

    https://gist.github.com/james-darkfox/595d22b7c48bd541cc39

    let matches = clap_app!(MyApp =>
        (@setting SubcommandRequiredElseHelp)
        (version: "1.0")
        (author: "Alice")
        (about: "Does awesome things")
        (@arg config: -c --config <conf> #{1, 2} {file_exists} "Sets a custom config file")
        (@arg input: * "Input file")
        (@group test =>
            (@attributes +required)
            (@arg output: "Sets an optional output file")
            (@arg debug: -d ... "Turn debugging information on")
        )
        (@subcommand test =>
            (about: "does testing things")
            (version: "2.5")
            (@arg list: -l "Lists test values")
            (@arg test_req: -r requires[list] "Tests requirement for listing")
            (@arg aaaa: --aaaa +takes_value {
                    |a| if a.contains("a") {
                        Ok(())
                    } else {
                        Err(String::from("string does not contain at least one a"))
                    }
                } "Test if the argument contains an a")
        )
    ).get_matches();
    

    Checklist

    • [x] App
      • [x] Version version: "1.2"
      • [x] Author author: "foo"
      • [x] About / description about: "foo"
      • [x] AppSettings @settings foo
    • [x] Argument groups @group foo => ... (implemented as a double accumulator)
      • [x] ArgGroup attributes
    • [x] Subcommands @subcommand foo => ...
      • [x] Subcommand attributes
    • [x] Argument attributes
      • [x] conflicts_with, conflicts_with_all conflicts_with[a b c]
      • [x] empty_values !deny_empty for false +deny_empty for true
      • [x] ~~from_usage~~
      • [x] global global
      • [x] group group(x)
      • [x] index index(n)
      • [x] long --long
      • [x] help "Help" LAST TOKEN
      • [x] max_values max_values(n)
      • [x] min_values min_values(n)
      • [x] multiple multiple
      • [x] mutually_overrides_with, mutually_overrides_with_all mutually_overrides_with[a b c]
      • [x] number_of_values number_of_values(n)
      • [x] possible_value, possible_values possible_values[a b c]
      • [x] required required *
      • [x] requires, requires_all requires[a b c]
      • [x] short -s
      • [x] takes_value +takes_value
      • [x] validator { |val| ... }
      • [x] value_name, value_names <var> [var] (Currently no difference between them)
      • [x] with_name (Forced; all arguments and apps must use this to define their name)
    • [x] 01c_quick_example.rs Much more complicated than the a/b samples
    • [x] Make the macro generic + shorthand
      • [x] Future proof macro design.
        • [x] Arg depends on: with_name long short takes_value required multiple value_name min_values max_values.
        • [x] App depends on: with_name arg_group subcommand setting arg.
        • [x] ArgGroup depends on: with_name add.
        • [x] The consumer may use more than this, but this is all the macro itself depends on
      • [x] Refactored down functions to builder functions
      • [x] Booleans factored down to +make_me_true and !make_me_false
      • [x] Added #{n, m} shorthand for min/max settings
        • [x] ~~Should there be shorthand for each side too? #{n, } #{, m} or #{n} #{0, m} ?~~
        • [x] ~~Should zero be caught and ignored for n?~~
      • [x] Added * shorthand for required
      • [x] <> and [] both imply takes_value while <> also implies required. They do not set either flag more than once. <> [] is equivalent to <> <> and [] <> is equivalent to [] []
      • [x] Renamed requires(a b c) to requires[a b c]
      • [x] Add shorthand for +foo = foo(true)
      • [x] Add shorthand for !foo = foo(false)
      • [x] ~~Add shorthand for *{foo bar} = requires readability~~
      • [x] ~~Add shorthand for !{foo bar} = conflicts readability~~
      • [x] ~~Add shorthand for ={foo bar} = possible values readability~~
      • [x] ~~Add shorthand for ~{foo bar} = mutually overrides readability~~
      • [x] Accumulate expressions instead of let builder = for cleaner result. Increases recursion depth
    • [x] Implement into crate and export macro
    • [ ] Document the macro usage
      • [x] Example
      • [ ] Detailed docs
    • [x] PR
    opened by WildCryptoFox 46
  • completions: Support adding additional code to complete values

    completions: Support adding additional code to complete values

    Closing comment:

    We currently provide ValueHint for leveraging shell logic, though it isn't customizable. For that, we have #1232.

    I'm inclined to close this in favor of wrapping up this request with #1232. I'm hesitant for us to have two different solutions (a Rust driven and shell-specific snippets) and doing shell snippets would couple args to completion so they would know what shell they are completing for.

    We can always expand how we are using ValueHint for the common cases and as a short term until we have full customization.


    For some argument values, the bash-completions may want to include additional logic for what type of value to complete, rather than allowing arbitrary strings. For instance, an option might accept a path to a file that exists; bash has a mechanism for that. Or, an option might accept the name of a git ref that exists; that's something more easily implemented in the program in Rust. Either way, it makes sense to augment clap's completion logic.

    This also argues for implementing the completions by calling the program at runtime, rather than via shell; that way, arbitrary logic in Rust can determine what to complete, rather than providing a template system to feed in shell code (ick).

    C-enhancement A-completion S-wont-fix 
    opened by joshtriplett 45
  • Hard to know how to respond to 3.2.0 deprecation messages in the derive API

    Hard to know how to respond to 3.2.0 deprecation messages in the derive API

    Maintainer's note:

    • As of 3.2.3, deprecations are behind the deprecated feature which is off by default for now (see #3830)
    • Until we improve the messages (if someone steps up to do so), See the release announcement for more details on the deprecations and cargo-deny for an example of how to migrate to clap 3.2 (with a tl;dr).
      • One simple way of reducing the messages is opting into unstable-v4 feature in your Cargo.toml. See the changelog for what else this affects.
    • Explanation of assumptions and circumstances that got us here

    Please complete the following tasks

    Rust Version

    rustc 1.61.0 (fe5b13d68 2022-05-18)

    Clap Version

    3.2.1 (or 3.2.0)

    Minimal reproducible code

    main.rs

    use clap::{Parser, Subcommand};
    
    #[derive(Parser, Debug)]
    #[clap(version, about, long_about = None)]
    struct Cli {
        #[clap(subcommand)]
        command: Commands,
    }
    
    #[derive(Subcommand, Debug)]
    enum Commands {
        /// Simple Command.
        GetArgs {
            /// Provide verbose diagnostic output.
            #[clap(short, long)]
            verbose: bool,
            /// Sample optional string.
            #[clap(long)]
            value: Option<String>,
            /// Just a list of valies
            list: Vec<String>
        },
    }
    
    fn main() {
        let cli = Cli::parse();
        match &cli.command {
            Commands::GetArgs { verbose, value, list } => {
                println!("verbose={:?}", verbose);
                println!("value={:?}", value);
                println!("list={:?}", list);
            }
        }
    }
    

    Cargo.toml

    [package]
    name = "test"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    clap = { version = "3.2.1", features = ["derive"] }
    

    Steps to reproduce the bug with the above code

    Use clap >= 3.2.0, this does not produce any warnings in 3.1.18.

    cargo build
    

    Actual Behaviour

    warning: use of deprecated unit variant `clap::ArgAction::StoreValue`: Replaced with `ArgAction::Set` or `ArgAction::Append`
      --> src/main.rs:17:9
       |
    17 | /         /// Sample optional string.
    18 | |         #[clap(long)]
    19 | |         value: Option<String>,
       | |_____________________________^
       |
       = note: `#[warn(deprecated)]` on by default
    
    warning: use of deprecated unit variant `clap::ArgAction::StoreValue`: Replaced with `ArgAction::Set` or `ArgAction::Append`
      --> src/main.rs:20:9
       |
    20 | /         /// Just a list of valies
    21 | |         list: Vec<String>
       | |_________________________^
    
    warning: use of deprecated associated function `clap::ArgMatches::is_present`: Replaced with either `ArgAction::SetTrue` or `ArgMatches::contains_id(...)`
      --> src/main.rs:16:18
       |
    16 |         verbose: bool,
       |                  ^^^^
    
    warning: use of deprecated associated function `clap::Arg::<'help>::validator`: Replaced with `Arg::value_parser(...)`
      --> src/main.rs:17:9
       |
    17 | /         /// Sample optional string.
    18 | |         #[clap(long)]
    19 | |         value: Option<String>,
       | |_____________________________^
    
    warning: use of deprecated associated function `clap::Arg::<'help>::multiple_occurrences`: Replaced with `Arg::action` (Issue #3772)
      --> src/main.rs:21:15
       |
    21 |         list: Vec<String>
       |               ^^^^^^^^^^^
    
    warning: use of deprecated associated function `clap::Arg::<'help>::validator`: Replaced with `Arg::value_parser(...)`
      --> src/main.rs:20:9
       |
    20 | /         /// Just a list of valies
    21 | |         list: Vec<String>
       | |_________________________^
    
    warning: `clap` (bin "clap") generated 6 warnings
        Finished dev [unoptimized + debuginfo] target(s) in 0.04s
         Running `target/debug/clap get-args`
    

    Expected Behaviour

    None of these warnings should occur, I believe.

    Additional Context

    No response

    Debug Output

    The debug output is the same as the above output.

    C-bug E-medium A-derive 
    opened by Alexhuszagh 44
  • Polishing `--help` output

    Polishing `--help` output

    We are looking to polish the help as part of the v4 release since some parts of an applications help might be dependent on how clap renders things (e.g. to match clap's ALL CAPS help headings, a user might put theirs in ALL CAPS).

    So far we have made the following changes:

    • The greens and yellows are gone, instead using bold, underline, and ~~dimmed~~: PR 4117 though some more work might be needed to enable colored help, depending on the needs
      • See PR for screenshot
      • Dimmed was removed from placeholders in https://github.com/clap-rs/clap/pull/4126
      • Some liked the colors (example), some hated them (example)
      • Color makes it easier to scan
      • Some applications have specific branding that it clashed with (#2963)
      • True colors would be prettier but requires getting into terminal theme detection to make sure it plays nice and hesistant to do that at the moment
      • Users can't rollback until theming support is in (https://github.com/clap-rs/clap/issues/3234) though they can just disable the coloring with Command::disable_colored_help(true)
    • Reduce the ALL CAPS: PR 4123
      • See PR for screenshot
      • ARGS and OPTIONS matched the usage and worked as non-colored headings but it feels a bit unpolished
      • I was hard pressed to find other CLIs that do this
      • All caps mirrors man pages
      • Mixed with underlining, it can be hard to see the bottom of "y", "g", etc.
      • Users can rollback to the old behavior with Command::help_template, Command:subcommand_help_heading, and Arg::help_heading
    • List subcommands before args/options: PR 4125
      • See PR for screenshot
      • At the end represents where someone might put it in the usage compared to everything else but generally a user's primary focus is on the subcommand they are going to call so that is where the help's focus should be
      • Users can rollback to the old behavior with Command::help_template
    • List of positional Arguments use [] for optional PR 4144
    • Always show optional positional arguments in usage, rather than collapsing them PR 4151
      • Generally there will be few enough positional arguments that this shouldn't be a big deal
      • Optional flags/options can be more numerous and clog up the usage, making it impossible to deal with (e.g. git)
    • Renaming SUBCOMMAND value name and Subcommand section headers to COMMAND and Command: PR 4155
      • "Subcommand" looks weird to me
      • Hard pressed to find other CLIs that do this
      • Users can rollback to the old behavior with Command::subcommand_help_heading and Command::subcommand_value_name
    • Hint to the user the difference between -h and --help: PR 4159
    • Remove <name> <verson> from the start of --help: PR 4160
      • It takes up precious vertical space but doesn't seem justified, especially when --version exists and when a subcommand doesn't have a version, it feels out of place (see cargo check -h)
      • Again, hard pressed to find other CLIs that do this
      • This does leave where to put authors if people specify them
      • Since all help is rendered from a template, this runs into problems when Command::about is unspecified as it leaves a blank line at the top of the help. https://github.com/clap-rs/clap/pull/4156 resolves that
      • Users can rollback to the old behavior with Command::help_template
    • Collapse usage to one line PR 4188
      • After looking at several CLIs, it seemed to fit and helps reduce length of output
      • See https://github.com/clap-rs/clap/issues/4132#issuecomment-1233007144 for alternatives considered
    • Reduce blank lines when overflowing short help onto next line PR 4190
    • Reduce indentation from 4 to 2 to reduce the chance of wrapping PR 4192
      • flags/options already have a lot of whitespace, we probably don't need as much everywhere
      • Inspired by podman -h
      • While https://github.com/clap-rs/clap/pull/4161 will make it easier to do on the implementation side, I'm losing steam and don't want to go update all of those tests

    Rejected

    • Some CLIs put Usage before the <about> and collapse it to Usage: <usage> if its a single line (e.g. find --help)
      • Putting usage closer to the arguments seems better
      • Otherwise, the difference seems trivial without a reason to go one way or the other
    • Should Arguments and Options be under a single heading by default?
      • I feel like there is a distinct enough difference in how they are used to call them out separately
      • A user can force them to be merged via Arg::help_heading

    Future improvements

    • https://github.com/clap-rs/clap/issues/2389
    • https://github.com/clap-rs/clap/issues/3234
    • https://github.com/clap-rs/clap/issues/3108
    • https://github.com/clap-rs/clap/issues/1433
    • https://github.com/clap-rs/clap/issues/1553

    Note: While I mentioning non-clap CLIs, I want to be clear that we don't just want to conform to what is out there. We should be aiming to make the defaults as polished as possible which can include taking inspiration from others.

    C-enhancement A-help S-waiting-on-design 
    opened by epage 42
  • Add hinting of arg value types for zsh/fish completion

    Add hinting of arg value types for zsh/fish completion

    Adds new method/attribute Arg::value_hint, taking a ValueHint enum as argument. The hint can denote accepted values, for example: paths, usernames, hostnames, commands, etc.

    This initial implementation supports hints for the zsh and fish completion generators, support for other shells can be added later.

    opened by intgr 38
  • WIP: Man page generation

    WIP: Man page generation

    I've been missing automatic man page generation for my CLI applications written using clap for a while, so I've decided to try/start to implement it on my own. This is currently a WIP, but it generates a very basic man page covering the arguments, positionals and subcommands with the most common sections that I've been able to find. I see that there has been a lot of movement on issues regarding help generation, so I may have started working on this at a bit of an unfortunate time :smile: This will close #552.

    The API should not be considered final, and is something I've cobbled together by looking at the shell completion generators and kinda worked it into an API for man pages. I'm creating this PR now to gather feedback on where to go from here and how it looks.

    Todos

    • [ ] Should we generated individual man pages per subcommand (like git does)
    • [ ] How to handle common extra sections (like "See also", "Examples" etc)
    • [ ] Should we include the date in the footer or just omit it?
    • [ ] How should positional arguments be handled in the output?
    Output from `man` example
    MYAPP(1)                                     GNU                                    MYAPP(1)
    
    NAME
           myapp - Does awesome things
    
    DESCRIPTION
           With a longer description to help clarify some things.
    
    SYNOPSIS
           myapp [--help] [--version] [-c|--config] [-d|--debug] [output]
    
    OPTIONS
           --help
               Print help information
    
           --version
               Print version information
    
           -c, --config FILE
               Sets a custom config file
    
               Some more text about how to set a custom config file
    
           -d, --debug
               Turn debugging information on
    
           [output]
               Sets an optional output file
    
    COMMANDS
           myapp-test(1)
           does testing things
    
    VERSION
           1.0
    
    AUTHOR(S)
           Kevin K. <[email protected]>
    
    myapp 1.0                                                                           MYAPP(1)
    
    opened by sondr3 32
  • clap_derive: Vec/Option<Vec> behavior is inconsistent with other types

    clap_derive: Vec/Option behavior is inconsistent with other types

    This is actually a summary of https://github.com/TeXitoi/structopt/issues/364

    Current behavior

    • Vec<T> and Option<Vec<T>> are not required = true by default.
    • Vec<T> is multiple = true by default which allows not only multiple values (--foo 1 2 3) but also multiple occurrences (--foo 1 --foo 2 3).
    • Option<Vec<T>> additionally allows zero number of values (--foo).

    What's wrong

    • The fact that Vec<T> is not required by default is inconsistent with all the other types in clap_derive that are required by default unless they are wrapped in Option (except bool but it's a very special case).
    • The fact that Option<Vec<T>> is different from Vec<T>, different not in "not required" sense, confuses newcomers.
    • The fact that Vec<T> allows multiple occurrences along with values is misleading.

    Proposal

    • Use min_values = 1 for both Option<Vec<T>> and Vec<T> instead of multiple = true, allowing only non-zero number of values and disallow multiple occurrences (--foo 1 2 but not --foo nor --foo 1 --foo 2). If a user wants to allow zero values or multiple occurrences as well, they can explicitly specify it via min_values = 0 and multiple = true respectively.
    • Use required = true for Vec<T>.

    cc @TeXitoi @Dylan-DPC @pksunkara

    C-enhancement A-derive 
    opened by CreepySkeleton 31
  • Help heading descriptions

    Help heading descriptions

    Discussed in https://github.com/clap-rs/clap/discussions/4588

    Originally posted by IgnisDa December 30, 2022 Hello. Awesome project!

    I want to display a help string after the help heading.

    image

    For reference, this is what it should end up looking like:

    image

    Is this possible?

    This is the code: https://github.com/IgnisDa/rust-libs/blob/53fcfb13510e69297ff98173239f962b3f4e97d5/crates/reflector/src/cli.rs#L83

    C-enhancement A-help S-waiting-on-design 
    opened by IgnisDa 1
  • Allow wrap_help without terminal_size dependency

    Allow wrap_help without terminal_size dependency

    Please complete the following tasks

    Clap Version

    4.0.30

    Describe your use case

    I would like to use clap for terminal wrapping but I would like to avoid using terminal_size as dependency. I do not need to make it dependent on the terminal size / I have my own way to read the terminal size. As such I wish there was a way to not pull in this rather heavy dependency while still having text wrapping available.

    Describe the solution you'd like

    • Make terminal_size something you need to opt in.
    • Alternatively add a wrap_help_core feature and have wrap_help depend on it and terminal_size

    Alternatives, if applicable

    No response

    Additional Context

    No response

    C-enhancement 
    opened by mitsuhiko 4
  • Implement more derive options for ArgGroup

    Implement more derive options for ArgGroup

    Please complete the following tasks

    Clap Version

    4.0.32

    Describe your use case

    clap_derive only supports the skip option for the group macro, as in #[group(skip)]. This is documented accordingly in https://docs.rs/clap/latest/clap/_derive/index.html#arggroup-attributes

    I wrote a struct that would benefit from having more options like requires, requires_all, conflicts_with, and conflicts_with_all:

    https://github.com/cargo-lambda/cargo-lambda/blob/main/crates/cargo-lambda-new/src/lib.rs#L37-L43 https://docs.rs/clap/latest/clap/builder/struct.ArgGroup.html

    Describe the solution you'd like

    I'd like to be able to use those options in the group macro.

    I don't mind to implement it myself if I can get some hints on how to do it, I've never contributed to this project and I'm a little bit lost in all the macro logic.

    Alternatives, if applicable

    No response

    Additional Context

    No response

    C-enhancement E-medium A-derive 
    opened by calavera 1
  • Nested flatten ignores positional parameters

    Nested flatten ignores positional parameters

    Please complete the following tasks

    Rust Version

    rustc 1.66.0 (69f9c33d7 2022-12-12)

    Clap Version

    4.0.30

    Minimal reproducible code

    use clap::Parser;
    
    #[derive(Parser, Debug, PartialEq, Default)]
    #[command(about, version)]
    pub struct Args {
        #[command(flatten)]
        val1: Option<SubArgs>,
    }
    
    #[derive(clap::Args, Debug, PartialEq, Default)]
    #[command(about, version)]
    pub struct SubArgs {
        val2: Vec<String>,
        #[command(flatten)]
        sub_val2: SubSubArgs,
    }
    
    #[derive(clap::Args, Debug, PartialEq, Default)]
    #[command(about, version)]
    pub struct SubSubArgs {
        #[arg(short, long)]
        pub val3: Option<i32>,
    }
    
    fn main() {
        let args = Args::parse_from(["main", "bar"]);
        let expected = Args {
            val1: Some(SubArgs {
                val2: vec!["bar".to_string()],
                sub_val2: SubSubArgs {
                    val3: None
                },
            }),
        };
        assert_eq!(args, expected);
    }
    

    Steps to reproduce the bug with the above code

    run it

    Actual Behaviour

    parse succeeds, but ignores the first positional parameter.

    Expected Behaviour

    first positional parameter should be added to the val2 Vec.

    Additional Context

    No response

    Debug Output

    /home/nyurik/.cargo/bin/cargo run --color=always --package tmp --bin tmp
        Finished dev [unoptimized + debuginfo] target(s) in 0.02s
         Running `target/debug/tmp`
    [      clap::builder::command] 	Command::_do_parse
    [      clap::builder::command] 	Command::_build: name="tmp"
    [      clap::builder::command] 	Command::_propagate:tmp
    [      clap::builder::command] 	Command::_check_help_and_version:tmp expand_help_tree=false
    [      clap::builder::command] 	Command::long_help_exists
    [      clap::builder::command] 	Command::_check_help_and_version: Building default --help
    [      clap::builder::command] 	Command::_check_help_and_version: Building default --version
    [      clap::builder::command] 	Command::_propagate_global_args:tmp
    [clap::builder::debug_asserts] 	Command::_debug_asserts
    [clap::builder::debug_asserts] 	Arg::_debug_asserts:val2
    [clap::builder::debug_asserts] 	Arg::_debug_asserts:val3
    [clap::builder::debug_asserts] 	Arg::_debug_asserts:help
    [clap::builder::debug_asserts] 	Arg::_debug_asserts:version
    [clap::builder::debug_asserts] 	Command::_verify_positionals
    [        clap::parser::parser] 	Parser::get_matches_with
    [        clap::parser::parser] 	Parser::get_matches_with: Begin parsing 'RawOsStr("bar")' ([98, 97, 114])
    [        clap::parser::parser] 	Parser::possible_subcommand: arg=Ok("bar")
    [        clap::parser::parser] 	Parser::get_matches_with: sc=None
    [        clap::parser::parser] 	Parser::get_matches_with: Positional counter...1
    [        clap::parser::parser] 	Parser::get_matches_with: Low index multiples...false
    [        clap::parser::parser] 	Parser::resolve_pending: id="val2"
    [        clap::parser::parser] 	Parser::react action=Append, identifier=Some(Index), source=CommandLine
    [        clap::parser::parser] 	Parser::remove_overrides: id="val2"
    [   clap::parser::arg_matcher] 	ArgMatcher::start_custom_arg: id="val2", source=CommandLine
    [      clap::builder::command] 	Command::groups_for_arg: id="val2"
    [        clap::parser::parser] 	Parser::push_arg_values: ["bar"]
    [        clap::parser::parser] 	Parser::add_single_val_to_arg: cur_idx:=1
    [   clap::parser::arg_matcher] 	ArgMatcher::needs_more_vals: o=val2, pending=0
    [   clap::parser::arg_matcher] 	ArgMatcher::needs_more_vals: expected=1..=18446744073709551615, actual=0
    [        clap::parser::parser] 	Parser::react not enough values passed in, leaving it to the validator to complain
    [        clap::parser::parser] 	Parser::add_defaults
    [        clap::parser::parser] 	Parser::add_defaults:iter:val2:
    [        clap::parser::parser] 	Parser::add_default_value: doesn't have conditional defaults
    [        clap::parser::parser] 	Parser::add_default_value:iter:val2: doesn't have default vals
    [        clap::parser::parser] 	Parser::add_defaults:iter:val3:
    [        clap::parser::parser] 	Parser::add_default_value: doesn't have conditional defaults
    [        clap::parser::parser] 	Parser::add_default_value:iter:val3: doesn't have default vals
    [        clap::parser::parser] 	Parser::add_defaults:iter:help:
    [        clap::parser::parser] 	Parser::add_default_value: doesn't have conditional defaults
    [        clap::parser::parser] 	Parser::add_default_value:iter:help: doesn't have default vals
    [        clap::parser::parser] 	Parser::add_defaults:iter:version:
    [        clap::parser::parser] 	Parser::add_default_value: doesn't have conditional defaults
    [        clap::parser::parser] 	Parser::add_default_value:iter:version: doesn't have default vals
    [     clap::parser::validator] 	Validator::validate
    [     clap::parser::validator] 	Validator::validate_conflicts
    [     clap::parser::validator] 	Validator::validate_exclusive
    [     clap::parser::validator] 	Validator::validate_conflicts::iter: id="val2"
    [     clap::parser::validator] 	Conflicts::gather_conflicts: arg="val2"
    [     clap::parser::validator] 	Conflicts::gather_conflicts: conflicts=[]
    [     clap::parser::validator] 	Validator::validate_required: required=ChildGraph([])
    [     clap::parser::validator] 	Validator::gather_requires
    [     clap::parser::validator] 	Validator::gather_requires:iter:"val2"
    [     clap::parser::validator] 	Validator::validate_required: is_exclusive_present=false
    [   clap::parser::arg_matcher] 	ArgMatcher::get_global_values: global_arg_vec=[]
    thread 'main' panicked at 'assertion failed: `(left == right)`
      left: `Args { val1: None }`,
     right: `Args { val1: Some(SubArgs { val2: ["bar"], sub_val2: SubSubArgs { val3: None } }) }`', src/main.rs:35:5
    stack backtrace:
       0: rust_begin_unwind
                 at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:575:5
       1: core::panicking::panic_fmt
                 at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/panicking.rs:65:14
       2: core::panicking::assert_failed_inner
       3: core::panicking::assert_failed
                 at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/panicking.rs:203:5
       4: tmp::main
                 at ./src/main.rs:35:5
       5: core::ops::function::FnOnce::call_once
                 at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/ops/function.rs:251:5
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    
    Process finished with exit code 101
    
    C-bug A-parsing E-medium 
    opened by nyurik 3
Releases(v4.0.32)
Owner
Crates related to clap (Argument Parsing Framework in Rust)
null
Docopt for Rust (command line argument parser).

THIS CRATE IS UNMAINTAINED This crate is unlikely to see significant future evolution. The primary reason to choose this crate for a new project is if

null 743 Jan 1, 2023
A simple, lightweight and extensible command line argument parser for rust codebases

A simple, lightweight and extensible command line argument parser for rust codebases. This crate aims to provide you with an easy-to-use and extensibl

Victor Ndaba 20 Nov 12, 2022
A minimal argument parser

Pieces An argument parser built with control in mind. Parsing The results you get are dependent on what order you parse in. If you want to say only pa

ibx34 3 Sep 30, 2021
argmax is a library that allows Rust applications to avoid Argument list too long errors (E2BIG) by providing a std::process::Command wrapper with a

argmax argmax is a library that allows Rust applications to avoid Argument list too long errors (E2BIG) by providing a std::process::Command wrapper w

David Peter 22 Nov 20, 2022
Rust derive-based argument parsing optimized for code size

Argh Argh is an opinionated Derive-based argument parser optimized for code size Derive-based argument parsing optimized for code size and conformance

Google 1.3k Dec 28, 2022
Argument parsing for the future 🚀

argi Argument parsing for the future ?? Features Macro-based approach, providing an intuitive way to layout a cli Rich auto-help generation, styling b

Owez 132 Oct 23, 2022
Small command-line tool to switch monitor inputs from command line

swmon Small command-line tool to switch monitor inputs from command line Installation git clone https://github.com/cr1901/swmon cargo install --path .

William D. Jones 5 Aug 20, 2022
Calc: A fully-featured minimalistic configurable calculator written in Rust

Calc Calc: A fully-featured minimalistic configurable rust calculator Install You can install the latest version from source git clone https://github.

Charlotte Thomas 4 Nov 15, 2023
Simple command line flag parser for rust.

easy_flag Simple command line flag parser for rust. use easy_flag::FlagSet; fn main() -> Result<(), String>{ let mut help = false; let mut my

BillyfBrain 3 Oct 20, 2021
A customizable MCTS planner with advanced featured tailored to multi-agent simulations and emergent narratives.

NPC engine Core:  Utils:  © 2020-2022 ETH Zurich and other contributors. See AUTHORS.txt for more details. A customizable Monte Carlo Tree Search (MCT

Game Technology Center, ETH Zurich 30 Jun 6, 2023
xcp is a (partial) clone of the Unix cp command. It is not intended as a full replacement

xcp is a (partial) clone of the Unix cp command. It is not intended as a full replacement, but as a companion utility with some more user-friendly feedback and some optimisations that make sense under certain tasks (see below).

Steve Smith 310 Jan 5, 2023
A language parser tool to build recursive descent top down parser.

lang-pt A language parser tool to generate recursive descent top down parser. Overview Parsers written for the languages like Javascript are often cus

Creative Forest 7 Jan 4, 2023
Command-line HTTP client for sending a POST request to specified URI on each stdin line.

line2httppost Simple tool to read lines from stdin and post each line as separate POST request to a specified URL (TCP connection is reused though). G

Vitaly Shukela 3 Jan 3, 2023
Pink is a command-line tool inspired by the Unix man command.

Pink is a command-line tool inspired by the Unix man command. It displays custom-formatted text pages in the terminal using a subset of HTML-like tags.

null 3 Nov 2, 2023
⚡️ Lightning-fast and minimal calendar command line. Written in Rust 🦀

⚡️ Lightning-fast and minimal calendar command line. It's similar to cal. Written in Rust ??

Arthur Henrique 36 Jan 1, 2023
Xsv - A fast CSV command line toolkit written in Rust.

xsv is a command line program for indexing, slicing, analyzing, splitting and joining CSV files. Commands should be simple, fast and composable: Simpl

Andrew Gallant 9.1k Dec 31, 2022
A blazing fast command line license generator for your open source projects written in Rust🚀

Overview This is a blazing fast ⚡ , command line license generator for your open source projects written in Rust. I know that GitHub

Shoubhit Dash 43 Dec 30, 2022
A blazingly fast command-line tool for converting Chinese punctuations to English punctuations

A blazingly fast command-line tool for converting Chinese punctuations to English punctuations

Hogan Lee 9 Dec 23, 2022