Crate clap [] [src]

clap

Travis-CI Crates.io Crates.io Join the chat at https://gitter.im/kbknapp/clap-rs

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 console, or terminal applications.

About

clap is used to parse and validate the string of command line arguments provided by the 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 also provides the traditional version and help switches (or flags) 'for free' meaning automatically with no configuration. It does this by checking list of valid possibilities you supplied and if you haven't them already (or only defined some of them), clap will auto-generate the applicable ones. If you are using subcommands, clap will also auto-generate a help subcommand for you in addition to the traditional flags.

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 of the mistake and exits gracefully. Because of this, you can make reasonable assumptions in your code about the validity of the arguments.

Features

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

Quick Example

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

NOTE: Both examples are functionally the same, but show two different styles in which to use clap

// (Full example with detailed comments in examples/01a_QuickExample.rs)
//
// This example demonstrates clap's "usage strings" method of creating arguments which is less
// less verbose
extern crate clap;
use clap::{Arg, App, SubCommand};

fn main() {
    let matches = App::new("myapp")
                          .version("1.0")
                          .author("Kevin K. <kbknapp@gmail.com>")
                          .about("Does awesome things")
                          .args_from_usage(
                              "-c --config=[CONFIG] 'Sets a custom config file'
                              <INPUT> 'Sets the input file to use'
                              [debug]... -d 'Sets the level of debugging information'")
                          .subcommand(SubCommand::with_name("test")
                                      .about("controls testing features")
                                      .version("1.3")
                                      .author("Someone E. <someone_else@other.com>")
                                      .arg_from_usage("-v --verbose 'Print test information verbosely'"))
                          .get_matches();

    // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
    // required we could have used an 'if let' to conditionally get the value)
    println!("Using input file: {}", matches.value_of("INPUT").unwrap());

    // Gets a value for config if supplied by user, or defaults to "default.conf"
    let config = matches.value_of("CONFIG").unwrap_or("default.conf");
    println!("Value for config: {}", config);

    // Vary the output based on how many times the user used the "debug" flag
    // (i.e. 'myapp -d -d -d' or 'myapp -ddd' vs 'myapp -d'
    match matches.occurrences_of("debug") {
        0 => println!("Debug mode is off"),
        1 => println!("Debug mode is kind of on"),
        2 => println!("Debug mode is on"),
        3 | _ => println!("Don't be crazy"),
    }

    // You can information about subcommands by requesting their matches by name
    // (as below), requesting just the name used, or both at the same time
    if let Some(matches) = matches.subcommand_matches("test") {
        if matches.is_present("verbose") {
            println!("Printing verbosely...");
        } else {
            println!("Printing normally...");
        }
    }

    // more porgram logic goes here...
}

The following example is functionally the same as the one above, but this method allows more advanced configuration options (not shown in this small example), or even dynamically generating arguments when desired. Both methods can be used together to get the best of both worlds (see the documentation, examples, or video tutorials).

// (Full example with detailed comments in examples/01b_QuickExample.rs)
//
// This example demonstrates clap's full 'builder pattern' style of creating arguments which is
// more verbose, but allows easier editting, and at times more advanced options, or the possibility
// to generate arguments dynamically.
extern crate clap;
use clap::{Arg, App, SubCommand};

fn main() {
    let matches = App::new("myapp")
                          .version("1.0")
                          .author("Kevin K. <kbknapp@gmail.com>")
                          .about("Does awesome things")
                          .arg(Arg::with_name("CONFIG")
                               .short("c")
                               .long("config")
                               .help("Sets a custom config file")
                               .takes_value(true))
                          .arg(Arg::with_name("INPUT")
                               .help("Sets the input file to use")
                               .required(true)
                               .index(1))
                          .arg(Arg::with_name("debug")
                               .short("d")
                               .multiple(true)
                               .help("Sets the level of debugging information"))
                          .subcommand(SubCommand::with_name("test")
                                      .about("controls testing features")
                                      .version("1.3")
                                      .author("Someone E. <someone_else@other.com>")
                                      .arg(Arg::with_name("verbose")
                                          .short("v")
                                          .help("print test information verbosely")))
                          .get_matches();

    // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
    // required we could have used an 'if let' to conditionally get the value)
    println!("Using input file: {}", matches.value_of("INPUT").unwrap());

    // Gets a value for config if supplied by user, or defaults to "default.conf"
    let config = matches.value_of("CONFIG").unwrap_or("default.conf");
    println!("Value for config: {}", config);

    // Vary the output based on how many times the user used the "debug" flag
    // (i.e. 'myapp -d -d -d' or 'myapp -ddd' vs 'myapp -d'
    match matches.occurrences_of("debug") {
        0 => println!("Debug mode is off"),
        1 => println!("Debug mode is kind of on"),
        2 => println!("Debug mode is on"),
        3 | _ => println!("Don't be crazy"),
    }

    // You can information about subcommands by requesting their matches by name
    // (as below), requesting just the name used, or both at the same time
    if let Some(matches) = matches.subcommand_matches("test") {
        if matches.is_present("verbose") {
            println!("Printing verbosely...");
        } else {
            println!("Printing normally...");
        }
    }

    // more porgram logic goes here...
}

If you were to compile either 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

$ myapp --help
myapp 1.0
Kevin K. <kbknapp@gmail.com>
Does awesome things

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

FLAGS:
    -d               Turn debugging information on
    -h, --help       Prints this message
    -v, --version    Prints version information

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

POSITIONAL ARGUMENTS:
    INPUT    The input file to use

SUBCOMMANDS:
    help    Prints this message
    test    Controls testing features

NOTE: You could also run myapp test --help to see similar output and options for the test subcommand.

Try it!

Pre-Built Test

To try out the pre-built example use the following stes:

BYOB (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 * Add clap to your Cargo.toml * ignore [dependencies] clap = "*"

extern crate clap;
use clap::App;

fn main() {
  let _ = App::new("fake").version("v1.0-beta").get_matches();
}

Usage

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

 [dependencies]
 clap = "*"

Or track the latest on the master branch at github:

[dependencies.clap]
git = "https://github.com/kbknapp/clap-rs.git"

Add extern crate clap; to your crate root.

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

If you'd like to keep your dependency list to only clap, you can disable any features that require an additional dependency. To do this, add this to your Cargo.toml:

[dependencies.clap]
version = "*"
default-features = false

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

[dependencies.clap]
version = "*"
default-features = false

features = [ "suggestions", "color" ]

The following is a list of optional clap features:

More Information

You can find complete documentation on the github-pages site for this project.

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

Video Tutorials

There's also the video tutorial series Argument Parsing with Rust that I've been working on.

Note: Two new videos have just been added (08 From Usage, and 09 Typed Values), if you're already familiar with clap but want to know more about these two details you can check out those videos without watching the previous few.

Note: Apologies for the resolution of the first video, it will be updated to a better resolution soon. The other videos have a proper resolution.

How to Contribute

Contributions are always welcome! And there is a multitude of ways in which you can help depending on what you like to do, or are good at. Anything from documentation, code cleanup, issue completion, new features, you name it, even filing issues is contributing and greatly appreciated!

  1. Fork the project
  2. Clone your fork (git clone https://github.com/$YOUR_USERNAME/clap-rs && cd clap-rs)
  3. Create new branch (git checkout -b new-branch)
  4. Make your changes, and commit (git commit -am "your message") (I try to use a conventional changelog format so I can update it using clog)
  5. If applicable, run the tests (See below)
  6. Push your changes back to your fork (git push origin your-branch)
  7. Create a pull request! (You can also create the pull request right away, and we'll merge when ready. This a good way to discuss proposed changes.)

Another really great way to help is if you find an interesting, or helpful way in which to use clap. You can either add it to the examples/ directory, or file an issue and tell me. I'm all about giving credit where credit is due :)

Running the tests

If contributing, you can run the tests as follows (assuming you're in the clap-rs/ directory)

cargo test && make -C clap-tests test

Goals

There are a few goals of clap that I'd like to maintain throughout contributions. If your proposed changes break, or go against any of these goals we'll discuss the changes further before merging (but will not be ignored, all contributes are welcome!). These are by no means hard-and-fast rules, as I'm no expert and break them myself from time to time (even if by mistake or ignorance :P).

License

clap is licensed under the MIT license. Please the LICENSE-MIT file in this repository for more information.

Recent Breaking Changes

Although I do my best to keep breaking changes to a minimum, being that this a sub 1.0 library, there are breaking changes from time to time in order to support better features or implementation. For the full details see the changelog.md

Deprecations

Old method names will be left around for some time.

Macros

arg_enum!

Convenience macro to generate more complete enums with variants to be used as a type when parsing arguments. This enum also provides a variants() function which can be used to retrieve a Vec<&'static str> of the variant names.

crate_version!

Allows you pull the version for an from your Cargo.toml as MAJOR.MINOR.PATCH_PKGVERSION_PRE

simple_enum!

Convenience macro generated a simple enum with variants to be used as a type when parsing arguments. This enum also provides a variants() function which can be used to retrieve a Vec<&'static str> of the variant names.

value_t!

Convenience macro getting a typed value T where T implements std::str::FromStr This macro returns a Result<T,String> which allows you as the developer to decide what you'd like to do on a failed parse. There are two types of errors, parse failures and those where the argument wasn't present (such as a non-required argument).

value_t_or_exit!

Convenience macro getting a typed value T where T implements std::str::FromStr This macro returns a T or Vec<T> or exits with a usage string upon failure. This removes some of the boiler plate to handle failures from value_t! above.

Structs

App

Used to create a representation of a command line program and all possible command line arguments.

Arg

The abstract representation of a command line argument used by the consumer of the library. Used to set all the options and relationships that define a valid argument for the program.

ArgGroup

ArgGroups are a family of related arguments and way for you to say, "Any of these arguments". By placing arguments in a logical group, you can make easier requirement and exclusion rules intead of having to list each individually, or when you want a rule to apply "any but not all" arguments.

ArgMatches

Used to get information about the arguments that where supplied to the program at runtime by the user. To get a new instance of this struct you use .get_matches() of the App struct.

SubCommand

The abstract representation of a command line subcommand used by the consumer of the library.

Enums

Format