clap/
lib.rs

1// Copyright ⓒ 2015-2016 Kevin B. Knapp and [`clap-rs` contributors](https://github.com/clap-rs/clap/blob/v2.33.1/CONTRIBUTORS.md).
2// Licensed under the MIT license
3// (see LICENSE or <http://opensource.org/licenses/MIT>) All files in the project carrying such
4// notice may not be copied, modified, or distributed except according to those terms.
5
6//! `clap` is a simple-to-use, efficient, and full-featured library for parsing command line
7//! arguments and subcommands when writing console/terminal applications.
8//!
9//! ## About
10//!
11//! `clap` is used to parse *and validate* the string of command line arguments provided by the user
12//! at runtime. You provide the list of valid possibilities, and `clap` handles the rest. This means
13//! you focus on your *applications* functionality, and less on the parsing and validating of
14//! arguments.
15//!
16//! `clap` also provides the traditional version and help switches (or flags) 'for free' meaning
17//! automatically with no configuration. It does this by checking the list of valid possibilities you
18//! supplied and adding only the ones you haven't already defined. If you are using subcommands,
19//! `clap` will also auto-generate a `help` subcommand for you in addition to the traditional flags.
20//!
21//! Once `clap` parses the user provided string of arguments, it returns the matches along with any
22//! applicable values. If the user made an error or typo, `clap` informs them of the mistake and
23//! exits gracefully (or returns a `Result` type and allows you to perform any clean up prior to
24//! exit). Because of this, you can make reasonable assumptions in your code about the validity of
25//! the arguments.
26//!
27//!
28//! ## Quick Example
29//!
30//! The following examples show a quick example of some of the very basic functionality of `clap`.
31//! For more advanced usage, such as requirements, conflicts, groups, multiple values and
32//! occurrences see the [documentation](https://docs.rs/clap/), [examples/] directory of
33//! this repository or the [video tutorials].
34//!
35//! **NOTE:** All of these examples are functionally the same, but show different styles in which to
36//! use `clap`
37//!
38//! The first example shows a method that allows more advanced configuration options (not shown in
39//! this small example), or even dynamically generating arguments when desired. The downside is it's
40//! more verbose.
41//!
42//! ```no_run
43//! // (Full example with detailed comments in examples/01b_quick_example.rs)
44//! //
45//! // This example demonstrates clap's full 'builder pattern' style of creating arguments which is
46//! // more verbose, but allows easier editing, and at times more advanced options, or the possibility
47//! // to generate arguments dynamically.
48//! extern crate clap;
49//! use clap::{Arg, App, SubCommand};
50//!
51//! fn main() {
52//!     let matches = App::new("My Super Program")
53//!                           .version("1.0")
54//!                           .author("Kevin K. <kbknapp@gmail.com>")
55//!                           .about("Does awesome things")
56//!                           .arg(Arg::with_name("config")
57//!                                .short("c")
58//!                                .long("config")
59//!                                .value_name("FILE")
60//!                                .help("Sets a custom config file")
61//!                                .takes_value(true))
62//!                           .arg(Arg::with_name("INPUT")
63//!                                .help("Sets the input file to use")
64//!                                .required(true)
65//!                                .index(1))
66//!                           .arg(Arg::with_name("v")
67//!                                .short("v")
68//!                                .multiple(true)
69//!                                .help("Sets the level of verbosity"))
70//!                           .subcommand(SubCommand::with_name("test")
71//!                                       .about("controls testing features")
72//!                                       .version("1.3")
73//!                                       .author("Someone E. <someone_else@other.com>")
74//!                                       .arg(Arg::with_name("debug")
75//!                                           .short("d")
76//!                                           .help("print debug information verbosely")))
77//!                           .get_matches();
78//!
79//!     // Gets a value for config if supplied by user, or defaults to "default.conf"
80//!     let config = matches.value_of("config").unwrap_or("default.conf");
81//!     println!("Value for config: {}", config);
82//!
83//!     // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
84//!     // required we could have used an 'if let' to conditionally get the value)
85//!     println!("Using input file: {}", matches.value_of("INPUT").unwrap());
86//!
87//!     // Vary the output based on how many times the user used the "verbose" flag
88//!     // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
89//!     match matches.occurrences_of("v") {
90//!         0 => println!("No verbose info"),
91//!         1 => println!("Some verbose info"),
92//!         2 => println!("Tons of verbose info"),
93//!         3 | _ => println!("Don't be crazy"),
94//!     }
95//!
96//!     // You can handle information about subcommands by requesting their matches by name
97//!     // (as below), requesting just the name used, or both at the same time
98//!     if let Some(matches) = matches.subcommand_matches("test") {
99//!         if matches.is_present("debug") {
100//!             println!("Printing debug info...");
101//!         } else {
102//!             println!("Printing normally...");
103//!         }
104//!     }
105//!
106//!     // more program logic goes here...
107//! }
108//! ```
109//!
110//! The next example shows a far less verbose method, but sacrifices some of the advanced
111//! configuration options (not shown in this small example). This method also takes a *very* minor
112//! runtime penalty.
113//!
114//! ```no_run
115//! // (Full example with detailed comments in examples/01a_quick_example.rs)
116//! //
117//! // This example demonstrates clap's "usage strings" method of creating arguments
118//! // which is less verbose
119//! extern crate clap;
120//! use clap::{Arg, App, SubCommand};
121//!
122//! fn main() {
123//!     let matches = App::new("myapp")
124//!                           .version("1.0")
125//!                           .author("Kevin K. <kbknapp@gmail.com>")
126//!                           .about("Does awesome things")
127//!                           .args_from_usage(
128//!                               "-c, --config=[FILE] 'Sets a custom config file'
129//!                               <INPUT>              'Sets the input file to use'
130//!                               -v...                'Sets the level of verbosity'")
131//!                           .subcommand(SubCommand::with_name("test")
132//!                                       .about("controls testing features")
133//!                                       .version("1.3")
134//!                                       .author("Someone E. <someone_else@other.com>")
135//!                                       .arg_from_usage("-d, --debug 'Print debug information'"))
136//!                           .get_matches();
137//!
138//!     // Same as previous example...
139//! }
140//! ```
141//!
142//! This third method shows how you can use a YAML file to build your CLI and keep your Rust source
143//! tidy or support multiple localized translations by having different YAML files for each
144//! localization.
145//!
146//! First, create the `cli.yml` file to hold your CLI options, but it could be called anything we
147//! like:
148//!
149//! ```yaml
150//! name: myapp
151//! version: "1.0"
152//! author: Kevin K. <kbknapp@gmail.com>
153//! about: Does awesome things
154//! args:
155//!     - config:
156//!         short: c
157//!         long: config
158//!         value_name: FILE
159//!         help: Sets a custom config file
160//!         takes_value: true
161//!     - INPUT:
162//!         help: Sets the input file to use
163//!         required: true
164//!         index: 1
165//!     - verbose:
166//!         short: v
167//!         multiple: true
168//!         help: Sets the level of verbosity
169//! subcommands:
170//!     - test:
171//!         about: controls testing features
172//!         version: "1.3"
173//!         author: Someone E. <someone_else@other.com>
174//!         args:
175//!             - debug:
176//!                 short: d
177//!                 help: print debug information
178//! ```
179//!
180//! Since this feature requires additional dependencies that not everyone may want, it is *not*
181//! compiled in by default and we need to enable a feature flag in Cargo.toml:
182//!
183//! Simply change your `clap = "~2.27.0"` to `clap = {version = "~2.27.0", features = ["yaml"]}`.
184//!
185//! At last we create our `main.rs` file just like we would have with the previous two examples:
186//!
187//! ```ignore
188//! // (Full example with detailed comments in examples/17_yaml.rs)
189//! //
190//! // This example demonstrates clap's building from YAML style of creating arguments which is far
191//! // more clean, but takes a very small performance hit compared to the other two methods.
192//! #[macro_use]
193//! extern crate clap;
194//! use clap::App;
195//!
196//! fn main() {
197//!     // The YAML file is found relative to the current file, similar to how modules are found
198//!     let yaml = load_yaml!("cli.yml");
199//!     let matches = App::from_yaml(yaml).get_matches();
200//!
201//!     // Same as previous examples...
202//! }
203//! ```
204//!
205//! Finally there is a macro version, which is like a hybrid approach offering the speed of the
206//! builder pattern (the first example), but without all the verbosity.
207//!
208//! ```no_run
209//! #[macro_use]
210//! extern crate clap;
211//!
212//! fn main() {
213//!     let matches = clap_app!(myapp =>
214//!         (version: "1.0")
215//!         (author: "Kevin K. <kbknapp@gmail.com>")
216//!         (about: "Does awesome things")
217//!         (@arg CONFIG: -c --config +takes_value "Sets a custom config file")
218//!         (@arg INPUT: +required "Sets the input file to use")
219//!         (@arg debug: -d ... "Sets the level of debugging information")
220//!         (@subcommand test =>
221//!             (about: "controls testing features")
222//!             (version: "1.3")
223//!             (author: "Someone E. <someone_else@other.com>")
224//!             (@arg verbose: -v --verbose "Print test information verbosely")
225//!         )
226//!     ).get_matches();
227//!
228//!     // Same as before...
229//! }
230//! ```
231//!
232//! If you were to compile any of the above programs and run them with the flag `--help` or `-h` (or
233//! `help` subcommand, since we defined `test` as a subcommand) the following would be output
234//!
235//! ```text
236//! $ myprog --help
237//! My Super Program 1.0
238//! Kevin K. <kbknapp@gmail.com>
239//! Does awesome things
240//!
241//! USAGE:
242//!     MyApp [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND]
243//!
244//! FLAGS:
245//!     -h, --help       Prints this message
246//!     -v               Sets the level of verbosity
247//!     -V, --version    Prints version information
248//!
249//! OPTIONS:
250//!     -c, --config <FILE>    Sets a custom config file
251//!
252//! ARGS:
253//!     INPUT    The input file to use
254//!
255//! SUBCOMMANDS:
256//!     help    Prints this message
257//!     test    Controls testing features
258//! ```
259//!
260//! **NOTE:** You could also run `myapp test --help` to see similar output and options for the
261//! `test` subcommand.
262//!
263//! ## Try it!
264//!
265//! ### Pre-Built Test
266//!
267//! To try out the pre-built example, use the following steps:
268//!
269//! * Clone the repository `$ git clone https://github.com/clap-rs/clap && cd clap-rs/tests`
270//! * Compile the example `$ cargo build --release`
271//! * Run the help info `$ ./target/release/claptests --help`
272//! * Play with the arguments!
273//!
274//! ### BYOB (Build Your Own Binary)
275//!
276//! To test out `clap`'s default auto-generated help/version follow these steps:
277//!
278//! * Create a new cargo project `$ cargo new fake --bin && cd fake`
279//! * Add `clap` to your `Cargo.toml`
280//!
281//! ```toml
282//! [dependencies]
283//! clap = "2"
284//! ```
285//!
286//! * Add the following to your `src/main.rs`
287//!
288//! ```no_run
289//! extern crate clap;
290//! use clap::App;
291//!
292//! fn main() {
293//!   App::new("fake").version("v1.0-beta").get_matches();
294//! }
295//! ```
296//!
297//! * Build your program `$ cargo build --release`
298//! * Run with help or version `$ ./target/release/fake --help` or `$ ./target/release/fake
299//! --version`
300//!
301//! ## Usage
302//!
303//! For full usage, add `clap` as a dependency in your `Cargo.toml` (it is **highly** recommended to
304//! use the `~major.minor.patch` style versions in your `Cargo.toml`, for more information see
305//! [Compatibility Policy](#compatibility-policy)) to use from crates.io:
306//!
307//! ```toml
308//! [dependencies]
309//! clap = "~2.27.0"
310//! ```
311//!
312//! Or get the latest changes from the master branch at github:
313//!
314//! ```toml
315//! [dependencies.clap]
316//! git = "https://github.com/clap-rs/clap.git"
317//! ```
318//!
319//! Add `extern crate clap;` to your crate root.
320//!
321//! Define a list of valid arguments for your program (see the
322//! [documentation](https://docs.rs/clap/) or [examples/] directory of this repo)
323//!
324//! Then run `cargo build` or `cargo update && cargo build` for your project.
325//!
326//! ### Optional Dependencies / Features
327//!
328//! #### Features enabled by default
329//!
330//! * `suggestions`: Turns on the `Did you mean '--myoption'?` feature for when users make typos. (builds dependency `strsim`)
331//! * `color`: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term` and `atty`)
332//! * `wrap_help`: Wraps the help at the actual terminal width when
333//!  available, instead of 120 characters. (builds dependency `textwrap`
334//! with feature `term_size`)
335//!
336//! To disable these, add this to your `Cargo.toml`:
337//!
338//! ```toml
339//! [dependencies.clap]
340//! version = "~2.27.0"
341//! default-features = false
342//! ```
343//!
344//! You can also selectively enable only the features you'd like to include, by adding:
345//!
346//! ```toml
347//! [dependencies.clap]
348//! version = "~2.27.0"
349//! default-features = false
350//!
351//! # Cherry-pick the features you'd like to use
352//! features = [ "suggestions", "color" ]
353//! ```
354//!
355//! #### Opt-in features
356//!
357//! * **"yaml"**: Enables building CLIs from YAML documents. (builds dependency `yaml-rust`)
358//! * **"unstable"**: Enables unstable `clap` features that may change from release to release
359//!
360//! ### Dependencies Tree
361//!
362//! The following graphic depicts `clap`s dependency graph (generated using
363//! [cargo-graph](https://github.com/kbknapp/cargo-graph)).
364//!
365//!  * **Dashed** Line: Optional dependency
366//!  * **Red** Color: **NOT** included by default (must use cargo `features` to enable)
367//!  * **Blue** Color: Dev dependency, only used while developing.
368//!
369//! ![clap dependencies](https://github.com/clap-rs/clap/blob/v2.34.0/clap_dep_graph.png)
370//!
371//! ### More Information
372//!
373//! You can find complete documentation on the [docs.rs](https://docs.rs/clap/) for this project.
374//!
375//! You can also find usage examples in the [examples/] directory of this repo.
376//!
377//! #### Video Tutorials
378//!
379//! There's also the video tutorial series [Argument Parsing with Rust v2][video tutorials].
380//!
381//! These videos slowly trickle out as I finish them and currently a work in progress.
382//!
383//! ## How to Contribute
384//!
385//! Contributions are always welcome! And there is a multitude of ways in which you can help
386//! depending on what you like to do, or are good at. Anything from documentation, code cleanup,
387//! issue completion, new features, you name it, even filing issues is contributing and greatly
388//! appreciated!
389//!
390//! Another really great way to help is if you find an interesting, or helpful way in which to use
391//! `clap`. You can either add it to the [examples/] directory, or file an issue and tell
392//! me. I'm all about giving credit where credit is due :)
393//!
394//! Please read [CONTRIBUTING.md](https://github.com/clap-rs/clap/blob/v2.34.0/.github/CONTRIBUTING.md) before you start contributing.
395//!
396//!
397//! ### Testing Code
398//!
399//! To test with all features both enabled and disabled, you can run theese commands:
400//!
401//! ```text
402//! $ cargo test --no-default-features
403//! $ cargo test --features "yaml unstable"
404//! ```
405//!
406//! Alternatively, if you have [`just`](https://github.com/casey/just) installed you can run the
407//! prebuilt recipes. *Not* using `just` is perfectly fine as well, it simply bundles commands
408//! automatically.
409//!
410//! For example, to test the code, as above simply run:
411//!
412//! ```text
413//! $ just run-tests
414//! ```
415//!
416//! From here on, I will list the appropriate `cargo` command as well as the `just` command.
417//!
418//! Sometimes it's helpful to only run a subset of the tests, which can be done via:
419//!
420//! ```text
421//! $ cargo test --test <test_name>
422//!
423//! # Or
424//!
425//! $ just run-test <test_name>
426//! ```
427//!
428//! ### Linting Code
429//!
430//! During the CI process `clap` runs against many different lints using
431//! [`clippy`](https://github.com/Manishearth/rust-clippy). In order to check if these lints pass on
432//! your own computer prior to submitting a PR you'll need a nightly compiler.
433//!
434//! In order to check the code for lints run either:
435//!
436//! ```text
437//! $ rustup override add nightly
438//! $ cargo build --features lints
439//! $ rustup override remove
440//!
441//! # Or
442//!
443//! $ just lint
444//! ```
445//!
446//! ### Debugging Code
447//!
448//! Another helpful technique is to see the `clap` debug output while developing features. In order
449//! to see the debug output while running the full test suite or individual tests, run:
450//!
451//! ```text
452//! $ cargo test --features debug
453//!
454//! # Or for individual tests
455//! $ cargo test --test <test_name> --features debug
456//!
457//! # The corresponding just command for individual debugging tests is:
458//! $ just debug <test_name>
459//! ```
460//!
461//! ### Goals
462//!
463//! There are a few goals of `clap` that I'd like to maintain throughout contributions. If your
464//! proposed changes break, or go against any of these goals we'll discuss the changes further
465//! before merging (but will *not* be ignored, all contributes are welcome!). These are by no means
466//! hard-and-fast rules, as I'm no expert and break them myself from time to time (even if by
467//! mistake or ignorance).
468//!
469//! * Remain backwards compatible when possible
470//!   - If backwards compatibility *must* be broken, use deprecation warnings if at all possible before
471//!   removing legacy code - This does not apply for security concerns
472//! * Parse arguments quickly
473//!   - Parsing of arguments shouldn't slow down usage of the main program - This is also true of
474//!   generating help and usage information (although *slightly* less stringent, as the program is about
475//!   to exit)
476//! * Try to be cognizant of memory usage
477//!   - Once parsing is complete, the memory footprint of `clap` should be low since the  main program
478//!   is the star of the show
479//! * `panic!` on *developer* error, exit gracefully on *end-user* error
480//!
481//! ### Compatibility Policy
482//!
483//! Because `clap` takes `SemVer` and compatibility seriously, this is the official policy regarding
484//! breaking changes and previous versions of Rust.
485//!
486//! `clap` will pin the minimum required version of Rust to the CI builds. Bumping the minimum
487//! version of Rust is considered a minor breaking change, meaning *at a minimum* the minor version
488//! of `clap` will be bumped.
489//!
490//! In order to keep from being surprised by breaking changes, it is **highly** recommended to use
491//! the `~major.minor.patch` style in your `Cargo.toml`:
492//!
493//! ```toml
494//! [dependencies] clap = "~2.27.0"
495//! ```
496//!
497//! This will cause *only* the patch version to be updated upon a `cargo update` call, and therefore
498//! cannot break due to new features, or bumped minimum versions of Rust.
499//!
500//! #### Minimum Version of Rust
501//!
502//! `clap` will officially support current stable Rust, minus two releases, but may work with prior
503//! releases as well. For example, current stable Rust at the time of this writing is 1.21.0,
504//! meaning `clap` is guaranteed to compile with 1.19.0 and beyond. At the 1.22.0 release, `clap`
505//! will be guaranteed to compile with 1.20.0 and beyond, etc.
506//!
507//! Upon bumping the minimum version of Rust (assuming it's within the stable-2 range), it *must* be
508//! clearly annotated in the `CHANGELOG.md`
509//!
510//! ## License
511//!
512//! `clap` is licensed under the MIT license. Please read the [LICENSE-MIT][license] file in
513//! this repository for more information.
514//!
515//! [examples/]: https://github.com/clap-rs/clap/tree/v2.34.0/examples
516//! [video tutorials]: https://www.youtube.com/playlist?list=PLza5oFLQGTl2Z5T8g1pRkIynR3E0_pc7U
517//! [license]: https://github.com/clap-rs/clap/blob/v2.34.0/LICENSE-MIT
518
519#![crate_type = "lib"]
520#![doc(html_root_url = "https://docs.rs/clap/2.34.0")]
521#![deny(
522    missing_docs,
523    missing_debug_implementations,
524    missing_copy_implementations,
525    trivial_casts,
526    unused_import_braces,
527    unused_allocation
528)]
529// Lints we'd like to deny but are currently failing for upstream crates
530//      unused_qualifications       (bitflags, clippy)
531//      trivial_numeric_casts       (bitflags)
532#![cfg_attr(
533    not(any(feature = "cargo-clippy", feature = "nightly")),
534    forbid(unstable_features)
535)]
536//#![cfg_attr(feature = "lints", feature(plugin))]
537//#![cfg_attr(feature = "lints", plugin(clippy))]
538// Need to disable deny(warnings) while deprecations are active
539//#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
540// Due to our "MSRV for 2.x will remain unchanged" policy, we can't fix these warnings
541#![allow(bare_trait_objects, deprecated)]
542
543#[cfg(all(feature = "color", not(target_os = "windows")))]
544extern crate ansi_term;
545#[cfg(feature = "color")]
546extern crate atty;
547#[macro_use]
548extern crate bitflags;
549#[cfg(feature = "suggestions")]
550extern crate strsim;
551#[cfg(feature = "wrap_help")]
552extern crate term_size;
553extern crate textwrap;
554extern crate unicode_width;
555#[cfg(feature = "vec_map")]
556extern crate vec_map;
557#[cfg(feature = "yaml")]
558extern crate yaml_rust;
559
560pub use app::{App, AppSettings};
561pub use args::{Arg, ArgGroup, ArgMatches, ArgSettings, OsValues, SubCommand, Values};
562pub use completions::Shell;
563pub use errors::{Error, ErrorKind, Result};
564pub use fmt::Format;
565#[cfg(feature = "yaml")]
566pub use yaml_rust::YamlLoader;
567
568#[macro_use]
569mod macros;
570mod app;
571mod args;
572mod completions;
573mod errors;
574mod fmt;
575mod map;
576mod osstringext;
577mod strext;
578mod suggestions;
579mod usage_parser;
580
581const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \
582                                          report at https://github.com/clap-rs/clap/issues";
583const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point";
584
585#[cfg(unstable)]
586pub use derive::{ArgEnum, ClapApp, FromArgMatches, IntoApp};
587
588#[cfg(unstable)]
589mod derive {
590    /// @TODO @release @docs
591    pub trait ClapApp: IntoApp + FromArgMatches + Sized {
592        /// @TODO @release @docs
593        fn parse() -> Self {
594            Self::from_argmatches(Self::into_app().get_matches())
595        }
596
597        /// @TODO @release @docs
598        fn parse_from<I, T>(argv: I) -> Self
599        where
600            I: IntoIterator<Item = T>,
601            T: Into<OsString> + Clone,
602        {
603            Self::from_argmatches(Self::into_app().get_matches_from(argv))
604        }
605
606        /// @TODO @release @docs
607        fn try_parse() -> Result<Self, clap::Error> {
608            Self::try_from_argmatches(Self::into_app().get_matches_safe()?)
609        }
610
611        /// @TODO @release @docs
612        fn try_parse_from<I, T>(argv: I) -> Result<Self, clap::Error>
613        where
614            I: IntoIterator<Item = T>,
615            T: Into<OsString> + Clone,
616        {
617            Self::try_from_argmatches(Self::into_app().get_matches_from_safe(argv)?)
618        }
619    }
620
621    /// @TODO @release @docs
622    pub trait IntoApp {
623        /// @TODO @release @docs
624        fn into_app<'a, 'b>() -> clap::App<'a, 'b>;
625    }
626
627    /// @TODO @release @docs
628    pub trait FromArgMatches: Sized {
629        /// @TODO @release @docs
630        fn from_argmatches<'a>(matches: clap::ArgMatches<'a>) -> Self;
631
632        /// @TODO @release @docs
633        fn try_from_argmatches<'a>(matches: clap::ArgMatches<'a>) -> Result<Self, clap::Error>;
634    }
635
636    /// @TODO @release @docs
637    pub trait ArgEnum {}
638}