Auto merge of #301 - kbknapp:issue-278, r=Vinatorul

Issue 278
This commit is contained in:
Homu 2015-10-02 03:40:23 +09:00
commit ec8070d9db
3 changed files with 165 additions and 153 deletions

View file

@ -2357,9 +2357,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
Some(matches.args.keys().map(|k| *k).collect()))); Some(matches.args.keys().map(|k| *k).collect())));
} }
if let Some(ref p_vals) = p.possible_vals { if let Some(ref p_vals) = p.possible_vals {
if !p_vals.contains(&arg_slice) { if !p_vals.contains(&arg_slice) {
return Err(self.possible_values_error(arg_slice, &p.to_string(), return Err(self.possible_values_error(arg_slice, &p.to_string(),
p_vals, matches)); p_vals, matches));
@ -2383,14 +2381,6 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
} }
} }
} }
if !p.settings.is_set(&ArgSettings::EmptyValues) && matches.args.contains_key(p.name) &&
arg_slice.is_empty() {
return Err(self.report_error(format!("The argument '{}' does not \
allow empty values, but one was found.",
Format::Warning(p.to_string())),
ClapErrorType::EmptyValue,
Some(matches.args.keys().map(|k| *k).collect())));
}
// Check if it's already existing and update if so... // Check if it's already existing and update if so...
if let Some(ref mut pos) = matches.args.get_mut(p.name) { if let Some(ref mut pos) = matches.args.get_mut(p.name) {
done = true; done = true;
@ -2400,6 +2390,11 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
vals.insert(len, arg_slice.to_owned()); vals.insert(len, arg_slice.to_owned());
} }
} }
if !pos_only && (self.settings.is_set(&AppSettings::TrailingVarArg) &&
pos_counter == self.positionals_idx.len() as u8) {
pos_only = true;
}
} else { } else {
// Only increment the positional counter if it doesn't allow multiples // Only increment the positional counter if it doesn't allow multiples
pos_counter += 1; pos_counter += 1;
@ -2420,13 +2415,6 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
} }
} }
let mut bm = BTreeMap::new(); let mut bm = BTreeMap::new();
if !p.settings.is_set(&ArgSettings::EmptyValues) && arg_slice.is_empty() {
return Err(self.report_error(format!("The argument '{}' does not \
allow empty values, but one was found.",
Format::Warning(p.to_string())),
ClapErrorType::EmptyValue,
Some(matches.args.keys().map(|k| *k).collect())));
}
if let Some(ref vtor) = p.validator { if let Some(ref vtor) = p.validator {
let f = &*vtor; let f = &*vtor;
if let Err(ref e) = f(arg_slice.to_owned()) { if let Err(ref e) = f(arg_slice.to_owned()) {

View file

@ -3,19 +3,20 @@ use std::ascii::AsciiExt;
bitflags! { bitflags! {
flags Flags: u32 { flags Flags: u32 {
const SC_NEGATE_REQS = 0b0000000000001, const SC_NEGATE_REQS = 0b00000000000001,
const SC_REQUIRED = 0b0000000000010, const SC_REQUIRED = 0b00000000000010,
const A_REQUIRED_ELSE_HELP = 0b0000000000100, const A_REQUIRED_ELSE_HELP = 0b00000000000100,
const GLOBAL_VERSION = 0b0000000001000, const GLOBAL_VERSION = 0b00000000001000,
const VERSIONLESS_SC = 0b0000000010000, const VERSIONLESS_SC = 0b00000000010000,
const UNIFIED_HELP = 0b0000000100000, const UNIFIED_HELP = 0b00000000100000,
const WAIT_ON_ERROR = 0b0000001000000, const WAIT_ON_ERROR = 0b00000001000000,
const SC_REQUIRED_ELSE_HELP= 0b0000010000000, const SC_REQUIRED_ELSE_HELP= 0b00000010000000,
const NEEDS_LONG_HELP = 0b0000100000000, const NEEDS_LONG_HELP = 0b00000100000000,
const NEEDS_LONG_VERSION = 0b0001000000000, const NEEDS_LONG_VERSION = 0b00001000000000,
const NEEDS_SC_HELP = 0b0010000000000, const NEEDS_SC_HELP = 0b00010000000000,
const DISABLE_VERSION = 0b0100000000000, const DISABLE_VERSION = 0b00100000000000,
const HIDDEN = 0b1000000000000, const HIDDEN = 0b01000000000000,
const TRAILING_VARARG = 0b10000000000000,
} }
} }
@ -41,6 +42,7 @@ impl AppFlags {
AppSettings::NeedsSubcommandHelp => self.0.insert(NEEDS_SC_HELP), AppSettings::NeedsSubcommandHelp => self.0.insert(NEEDS_SC_HELP),
AppSettings::DisableVersion => self.0.insert(DISABLE_VERSION), AppSettings::DisableVersion => self.0.insert(DISABLE_VERSION),
AppSettings::Hidden => self.0.insert(HIDDEN), AppSettings::Hidden => self.0.insert(HIDDEN),
AppSettings::TrailingVarArg => self.0.insert(TRAILING_VARARG),
} }
} }
@ -59,6 +61,7 @@ impl AppFlags {
AppSettings::NeedsSubcommandHelp => self.0.remove(NEEDS_SC_HELP), AppSettings::NeedsSubcommandHelp => self.0.remove(NEEDS_SC_HELP),
AppSettings::DisableVersion => self.0.remove(DISABLE_VERSION), AppSettings::DisableVersion => self.0.remove(DISABLE_VERSION),
AppSettings::Hidden => self.0.remove(HIDDEN), AppSettings::Hidden => self.0.remove(HIDDEN),
AppSettings::TrailingVarArg => self.0.remove(TRAILING_VARARG),
} }
} }
@ -77,6 +80,7 @@ impl AppFlags {
AppSettings::NeedsSubcommandHelp => self.0.contains(NEEDS_SC_HELP), AppSettings::NeedsSubcommandHelp => self.0.contains(NEEDS_SC_HELP),
AppSettings::DisableVersion => self.0.contains(DISABLE_VERSION), AppSettings::DisableVersion => self.0.contains(DISABLE_VERSION),
AppSettings::Hidden => self.0.contains(HIDDEN), AppSettings::Hidden => self.0.contains(HIDDEN),
AppSettings::TrailingVarArg => self.0.contains(TRAILING_VARARG),
} }
} }
} }
@ -232,6 +236,26 @@ pub enum AppSettings {
/// # ; /// # ;
/// ``` /// ```
Hidden, Hidden,
/// Specifies that the final positional argument is a vararg and that `clap` should not attempt
/// to parse any further args.
///
/// The values of the trailing positional argument will contain all args from itself on.
///
/// **NOTE:** The final positional argument **must** have `.multiple(true)` or usage token
/// equivilant.
///
/// # Examples
///
/// ```no_run
/// # use clap::{App, Arg, AppSettings};
/// let m = App::new("myprog")
/// .setting(AppSettings::TrailingVarArg)
/// .arg(Arg::from_usage("<cmd>... 'commands to run'"))
/// .get_matches_from(vec!["myprog", "some_command", "-r", "set"]);
///
/// assert_eq!(m.values_of("cmd").unwrap(), &["some_command", "-r", "set"]);
/// ```
TrailingVarArg,
#[doc(hidden)] #[doc(hidden)]
NeedsLongVersion, NeedsLongVersion,
#[doc(hidden)] #[doc(hidden)]

View file

@ -8,37 +8,37 @@
//#![cfg_attr(feature = "lints", allow(unknown_lints))] //#![cfg_attr(feature = "lints", allow(unknown_lints))]
/// Command Line Argument Parser for Rust /// Command Line Argument Parser for Rust
/// ///
/// It is a simple to use, efficient, and full featured library for parsing command line arguments /// It is a simple to use, efficient, and full featured library for parsing command line arguments
/// and subcommands when writing console, or terminal applications. /// and subcommands when writing console, or terminal applications.
/// ///
/// ## About /// ## About
/// ///
/// `clap` is used to parse *and validate* the string of command line arguments provided by the /// `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 /// 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 /// means you focus on your *applications* functionality, and less on the parsing and validating of
/// arguments. /// arguments.
/// ///
/// `clap` also provides the traditional version and help switches (or flags) 'for free' meaning /// `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 /// 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- /// 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 /// 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. /// `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 /// 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 /// 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 /// exits gracefully. Because of this, you can make reasonable assumptions in your code about the
/// validity of the arguments. /// validity of the arguments.
/// ///
/// ## Quick Examples /// ## Quick Examples
/// ///
/// The following examples show a quick example of some of the very basic functionality of `clap`. /// The following 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 /// For more advanced usage, such as requirements, exclusions, groups, multiple values and
/// occurrences see the [video tutorials](https://www.youtube.com/playlist?list=PLza5oFLQGTl0Bc_EU_pBNcX-rhVqDTRxv), /// occurrences see the [video tutorials](https://www.youtube.com/playlist?list=PLza5oFLQGTl0Bc_EU_pBNcX-rhVqDTRxv),
/// [documentation](http://kbknapp.github.io/clap-rs/clap/index.html), or [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples) /// [documentation](http://kbknapp.github.io/clap-rs/clap/index.html), or [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples)
/// directory of this repository. /// directory of this repository.
/// ///
/// **NOTE:** All these examples are functionally the same, but show three different styles in /// **NOTE:** All these examples are functionally the same, but show three different styles in
/// which to use `clap` /// which to use `clap`
/// ///
/// ```no_run /// ```no_run
@ -48,7 +48,7 @@
/// // less verbose /// // less verbose
/// extern crate clap; /// extern crate clap;
/// use clap::{Arg, App, SubCommand}; /// use clap::{Arg, App, SubCommand};
/// ///
/// fn main() { /// fn main() {
/// let matches = App::new("myapp") /// let matches = App::new("myapp")
/// .version("1.0") /// .version("1.0")
@ -64,15 +64,15 @@
/// .author("Someone E. <someone_else@other.com>") /// .author("Someone E. <someone_else@other.com>")
/// .arg_from_usage("-v --verbose 'Print test information verbosely'")) /// .arg_from_usage("-v --verbose 'Print test information verbosely'"))
/// .get_matches(); /// .get_matches();
/// ///
/// // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't /// // 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) /// // required we could have used an 'if let' to conditionally get the value)
/// println!("Using input file: {}", matches.value_of("INPUT").unwrap()); /// println!("Using input file: {}", matches.value_of("INPUT").unwrap());
/// ///
/// // Gets a value for config if supplied by user, or defaults to "default.conf" /// // Gets a value for config if supplied by user, or defaults to "default.conf"
/// let config = matches.value_of("CONFIG").unwrap_or("default.conf"); /// let config = matches.value_of("CONFIG").unwrap_or("default.conf");
/// println!("Value for config: {}", config); /// println!("Value for config: {}", config);
/// ///
/// // Vary the output based on how many times the user used the "debug" flag /// // 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' /// // (i.e. 'myapp -d -d -d' or 'myapp -ddd' vs 'myapp -d'
/// match matches.occurrences_of("debug") { /// match matches.occurrences_of("debug") {
@ -81,7 +81,7 @@
/// 2 => println!("Debug mode is on"), /// 2 => println!("Debug mode is on"),
/// 3 | _ => println!("Don't be crazy"), /// 3 | _ => println!("Don't be crazy"),
/// } /// }
/// ///
/// // You can information about subcommands by requesting their matches by name /// // You can information about subcommands by requesting their matches by name
/// // (as below), requesting just the name used, or both at the same time /// // (as below), requesting just the name used, or both at the same time
/// if let Some(matches) = matches.subcommand_matches("test") { /// if let Some(matches) = matches.subcommand_matches("test") {
@ -91,17 +91,17 @@
/// println!("Printing normally..."); /// println!("Printing normally...");
/// } /// }
/// } /// }
/// ///
/// // more program logic goes here... /// // more program logic goes here...
/// } /// }
/// ``` /// ```
/// ///
/// The following example is functionally the same as the one above, but this method allows more /// 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 /// 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 /// generating arguments when desired. Both methods can be used together to get the best of both
/// worlds (see the documentation, [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples), /// worlds (see the documentation, [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples),
/// or video tutorials). /// or video tutorials).
/// ///
/// ```no_run /// ```no_run
/// // (Full example with detailed comments in examples/01b_quick_example.rs) /// // (Full example with detailed comments in examples/01b_quick_example.rs)
/// // /// //
@ -110,7 +110,7 @@
/// // to generate arguments dynamically. /// // to generate arguments dynamically.
/// extern crate clap; /// extern crate clap;
/// use clap::{Arg, App, SubCommand}; /// use clap::{Arg, App, SubCommand};
/// ///
/// fn main() { /// fn main() {
/// let matches = App::new("myapp") /// let matches = App::new("myapp")
/// .version("1.0") /// .version("1.0")
@ -137,15 +137,15 @@
/// .short("v") /// .short("v")
/// .help("print test information verbosely"))) /// .help("print test information verbosely")))
/// .get_matches(); /// .get_matches();
/// ///
/// // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't /// // 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) /// // required we could have used an 'if let' to conditionally get the value)
/// println!("Using input file: {}", matches.value_of("INPUT").unwrap()); /// println!("Using input file: {}", matches.value_of("INPUT").unwrap());
/// ///
/// // Gets a value for config if supplied by user, or defaults to "default.conf" /// // Gets a value for config if supplied by user, or defaults to "default.conf"
/// let config = matches.value_of("CONFIG").unwrap_or("default.conf"); /// let config = matches.value_of("CONFIG").unwrap_or("default.conf");
/// println!("Value for config: {}", config); /// println!("Value for config: {}", config);
/// ///
/// // Vary the output based on how many times the user used the "debug" flag /// // 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' /// // (i.e. 'myapp -d -d -d' or 'myapp -ddd' vs 'myapp -d'
/// match matches.occurrences_of("debug") { /// match matches.occurrences_of("debug") {
@ -154,7 +154,7 @@
/// 2 => println!("Debug mode is on"), /// 2 => println!("Debug mode is on"),
/// 3 | _ => println!("Don't be crazy"), /// 3 | _ => println!("Don't be crazy"),
/// } /// }
/// ///
/// // You can information about subcommands by requesting their matches by name /// // You can information about subcommands by requesting their matches by name
/// // (as below), requesting just the name used, or both at the same time /// // (as below), requesting just the name used, or both at the same time
/// if let Some(matches) = matches.subcommand_matches("test") { /// if let Some(matches) = matches.subcommand_matches("test") {
@ -164,14 +164,14 @@
/// println!("Printing normally..."); /// println!("Printing normally...");
/// } /// }
/// } /// }
/// ///
/// // more program logic goes here... /// // more program logic goes here...
/// } /// }
/// ``` /// ```
/// ///
/// The following combines the previous two examples by using the simplicity of the `from_usage` /// The following combines the previous two examples by using the simplicity of the `from_usage`
/// methods and the performance of the Builder Pattern. /// methods and the performance of the Builder Pattern.
/// ///
/// ```no_run /// ```no_run
/// // (Full example with detailed comments in examples/01c_quick_example.rs) /// // (Full example with detailed comments in examples/01c_quick_example.rs)
/// // /// //
@ -179,7 +179,7 @@
/// // less verbose /// // less verbose
/// #[macro_use] /// #[macro_use]
/// extern crate clap; /// extern crate clap;
/// ///
/// fn main() { /// fn main() {
/// let matches = clap_app!(myapp => /// let matches = clap_app!(myapp =>
/// (version: "1.0") /// (version: "1.0")
@ -195,15 +195,15 @@
/// (@arg verbose: -v --verbose "Print test information verbosely") /// (@arg verbose: -v --verbose "Print test information verbosely")
/// ) /// )
/// ).get_matches(); /// ).get_matches();
/// ///
/// // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't /// // 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) /// // required we could have used an 'if let' to conditionally get the value)
/// println!("Using input file: {}", matches.value_of("INPUT").unwrap()); /// println!("Using input file: {}", matches.value_of("INPUT").unwrap());
/// ///
/// // Gets a value for config if supplied by user, or defaults to "default.conf" /// // Gets a value for config if supplied by user, or defaults to "default.conf"
/// let config = matches.value_of("CONFIG").unwrap_or("default.conf"); /// let config = matches.value_of("CONFIG").unwrap_or("default.conf");
/// println!("Value for config: {}", config); /// println!("Value for config: {}", config);
/// ///
/// // Vary the output based on how many times the user used the "debug" flag /// // 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' /// // (i.e. 'myapp -d -d -d' or 'myapp -ddd' vs 'myapp -d'
/// match matches.occurrences_of("debug") { /// match matches.occurrences_of("debug") {
@ -212,7 +212,7 @@
/// 2 => println!("Debug mode is on"), /// 2 => println!("Debug mode is on"),
/// 3 | _ => println!("Don't be crazy"), /// 3 | _ => println!("Don't be crazy"),
/// } /// }
/// ///
/// // You can information about subcommands by requesting their matches by name /// // You can information about subcommands by requesting their matches by name
/// // (as below), requesting just the name used, or both at the same time /// // (as below), requesting just the name used, or both at the same time
/// if let Some(matches) = matches.subcommand_matches("test") { /// if let Some(matches) = matches.subcommand_matches("test") {
@ -222,15 +222,15 @@
/// println!("Printing normally..."); /// println!("Printing normally...");
/// } /// }
/// } /// }
/// ///
/// // more program logic goes here... /// // more program logic goes here...
/// } /// }
/// ``` /// ```
/// ///
/// This final method shows how you can use a YAML file to build your CLI and keep your Rust source /// This final method shows how you can use a YAML file to build your CLI and keep your Rust source
/// tidy. First, create the `cli.yml` file to hold your CLI options, but it could be called /// tidy. First, create the `cli.yml` file to hold your CLI options, but it could be called
/// anything we like (we'll use the same both examples above to keep it functionally equivilant): /// anything we like (we'll use the same both examples above to keep it functionally equivilant):
/// ///
/// ```ignore /// ```ignore
/// name: myapp /// name: myapp
/// version: 1.0 /// version: 1.0
@ -260,9 +260,9 @@
/// short: v /// short: v
/// help: print test information verbosely /// help: print test information verbosely
/// ``` /// ```
/// ///
/// Now we create our `main.rs` file just like we would have with the previous two examples: /// Now we create our `main.rs` file just like we would have with the previous two examples:
/// ///
/// ```ignore /// ```ignore
/// // (Full example with detailed comments in examples/17_yaml.rs) /// // (Full example with detailed comments in examples/17_yaml.rs)
/// // /// //
@ -271,20 +271,20 @@
/// #[macro_use] /// #[macro_use]
/// extern crate clap; /// extern crate clap;
/// use clap::App; /// use clap::App;
/// ///
/// fn main() { /// fn main() {
/// // The YAML file is found relative to the current file, similar to how modules are found /// // The YAML file is found relative to the current file, similar to how modules are found
/// let yaml = load_yaml!("cli.yml"); /// let yaml = load_yaml!("cli.yml");
/// let matches = App::from_yaml(yaml).get_matches(); /// let matches = App::from_yaml(yaml).get_matches();
/// ///
/// // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't /// // 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) /// // required we could have used an 'if let' to conditionally get the value)
/// println!("Using input file: {}", matches.value_of("INPUT").unwrap()); /// println!("Using input file: {}", matches.value_of("INPUT").unwrap());
/// ///
/// // Gets a value for config if supplied by user, or defaults to "default.conf" /// // Gets a value for config if supplied by user, or defaults to "default.conf"
/// let config = matches.value_of("CONFIG").unwrap_or("default.conf"); /// let config = matches.value_of("CONFIG").unwrap_or("default.conf");
/// println!("Value for config: {}", config); /// println!("Value for config: {}", config);
/// ///
/// // Vary the output based on how many times the user used the "debug" flag /// // 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' /// // (i.e. 'myapp -d -d -d' or 'myapp -ddd' vs 'myapp -d'
/// match matches.occurrences_of("debug") { /// match matches.occurrences_of("debug") {
@ -293,7 +293,7 @@
/// 2 => println!("Debug mode is on"), /// 2 => println!("Debug mode is on"),
/// 3 | _ => println!("Don't be crazy"), /// 3 | _ => println!("Don't be crazy"),
/// } /// }
/// ///
/// // You can information about subcommands by requesting their matches by name /// // You can information about subcommands by requesting their matches by name
/// // (as below), requesting just the name used, or both at the same time /// // (as below), requesting just the name used, or both at the same time
/// if let Some(matches) = matches.subcommand_matches("test") { /// if let Some(matches) = matches.subcommand_matches("test") {
@ -303,60 +303,60 @@
/// println!("Printing normally..."); /// println!("Printing normally...");
/// } /// }
/// } /// }
/// ///
/// // more program logic goes here... /// // more program logic goes here...
/// } /// }
/// ``` /// ```
/// ///
/// If you were to compile any of the above programs and run them with the flag `--help` or `-h` /// 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 /// (or `help` subcommand, since we defined `test` as a subcommand) the following would be output
/// ///
/// **NOTE**: The YAML option requires adding a special `features` flag when compiling `clap` /// **NOTE**: The YAML option requires adding a special `features` flag when compiling `clap`
/// because it is not compiled by default since it takes additional dependencies that some people /// because it is not compiled by default since it takes additional dependencies that some people
/// may not need. Simply change your `clap = "1"` to `clap = {version = "1", features = ["yaml"]}` /// may not need. Simply change your `clap = "1"` to `clap = {version = "1", features = ["yaml"]}`
/// in your `Cargo.toml` to use the YAML version. /// in your `Cargo.toml` to use the YAML version.
/// ///
/// ```ignore /// ```ignore
/// $ myapp --help /// $ myapp --help
/// myapp 1.0 /// myapp 1.0
/// Kevin K. <kbknapp@gmail.com> /// Kevin K. <kbknapp@gmail.com>
/// Does awesome things /// Does awesome things
/// ///
/// USAGE: /// USAGE:
/// MyApp [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND] /// MyApp [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND]
/// ///
/// FLAGS: /// FLAGS:
/// -d Turn debugging information on /// -d Turn debugging information on
/// -h, --help Prints this message /// -h, --help Prints this message
/// -V, --version Prints version information /// -V, --version Prints version information
/// ///
/// OPTIONS: /// OPTIONS:
/// -c, --config <CONFIG> Sets a custom config file /// -c, --config <CONFIG> Sets a custom config file
/// ///
/// ARGS: /// ARGS:
/// INPUT The input file to use /// INPUT The input file to use
/// ///
/// SUBCOMMANDS: /// SUBCOMMANDS:
/// help Prints this message /// help Prints this message
/// test Controls testing features /// test Controls testing features
/// ``` /// ```
/// ///
/// **NOTE:** You could also run `myapp test --help` to see similar output and options for the /// **NOTE:** You could also run `myapp test --help` to see similar output and options for the
/// `test` subcommand. /// `test` subcommand.
/// ///
/// ## Try it! /// ## Try it!
/// ///
/// ### Pre-Built Test /// ### Pre-Built Test
/// ///
/// To try out the pre-built example, use the following steps: /// To try out the pre-built example, use the following steps:
/// ///
/// * Clone the repo `$ git clone https://github.com/kbknapp/clap-rs && cd clap-rs/clap-tests` /// * Clone the repo `$ git clone https://github.com/kbknapp/clap-rs && cd clap-rs/clap-tests`
/// * Compile the example `$ cargo build --release` /// * Compile the example `$ cargo build --release`
/// * Run the help info `$ ./target/release/claptests --help` /// * Run the help info `$ ./target/release/claptests --help`
/// * Play with the arguments! /// * Play with the arguments!
/// ///
/// ### BYOB (Build Your Own Binary) /// ### BYOB (Build Your Own Binary)
/// ///
/// To test out `clap`'s default auto-generated help/version follow these steps: /// To test out `clap`'s default auto-generated help/version follow these steps:
/// * Create a new cargo project `$ cargo new fake --bin && cd fake` /// * Create a new cargo project `$ cargo new fake --bin && cd fake`
/// * Add `clap` to your `Cargo.toml` /// * Add `clap` to your `Cargo.toml`
@ -365,117 +365,117 @@
/// [dependencies] /// [dependencies]
/// clap = "1" /// clap = "1"
/// ``` /// ```
/// ///
/// * Add the following to your `src/main.rs` /// * Add the following to your `src/main.rs`
/// ///
/// ```no_run /// ```no_run
/// extern crate clap; /// extern crate clap;
/// use clap::App; /// use clap::App;
/// ///
/// fn main() { /// fn main() {
/// let _ = App::new("fake").version("v1.0-beta").get_matches(); /// let _ = App::new("fake").version("v1.0-beta").get_matches();
/// } /// }
/// ``` /// ```
/// ///
/// * Build your program `$ cargo build --release` /// * Build your program `$ cargo build --release`
/// * Run w/ help or version `$ ./target/release/fake --help` or `$ ./target/release/fake --version` /// * Run w/ help or version `$ ./target/release/fake --help` or `$ ./target/release/fake --version`
/// ///
/// ## Usage /// ## Usage
/// ///
/// For full usage, add `clap` as a dependency in your `Cargo.toml` file to use from crates.io: /// For full usage, add `clap` as a dependency in your `Cargo.toml` file to use from crates.io:
/// ///
/// ```ignore /// ```ignore
/// [dependencies] /// [dependencies]
/// clap = "1" /// clap = "1"
/// ``` /// ```
/// Or track the latest on the master branch at github: /// Or track the latest on the master branch at github:
/// ///
/// ```ignore /// ```ignore
/// [dependencies.clap] /// [dependencies.clap]
/// git = "https://github.com/kbknapp/clap-rs.git" /// git = "https://github.com/kbknapp/clap-rs.git"
/// ``` /// ```
/// ///
/// Add `extern crate clap;` to your crate root. /// Add `extern crate clap;` to your crate root.
/// ///
/// Define a list of valid arguments for your program (see the [documentation](https://kbknapp.github.io/clap-rs/index.html) /// Define a list of valid arguments for your program (see the [documentation](https://kbknapp.github.io/clap-rs/index.html)
/// or [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples) directory of this repo) /// or [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples) directory of this repo)
/// ///
/// Then run `cargo build` or `cargo update && cargo build` for your project. /// Then run `cargo build` or `cargo update && cargo build` for your project.
/// ///
/// ### Optional Dependencies / Features /// ### Optional Dependencies / Features
/// ///
/// If you'd like to keep your dependency list to **only** `clap`, you can disable any 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`: /// that require an additional dependency. To do this, add this to your `Cargo.toml`:
/// ///
/// ```ignore /// ```ignore
/// [dependencies.clap] /// [dependencies.clap]
/// version = "1" /// version = "1"
/// default-features = false /// default-features = false
/// ``` /// ```
/// ///
/// You can also selectively enable only the features you'd like to include, by adding: /// You can also selectively enable only the features you'd like to include, by adding:
/// ///
/// ```ignore /// ```ignore
/// [dependencies.clap] /// [dependencies.clap]
/// version = "1" /// version = "1"
/// default-features = false /// default-features = false
/// ///
/// # Cherry-pick the features you'd like to use /// # Cherry-pick the features you'd like to use
/// features = [ "suggestions", "color" ] /// features = [ "suggestions", "color" ]
/// ``` /// ```
/// ///
/// The following is a list of optional `clap` features: /// The following is a list of optional `clap` features:
/// ///
/// * **"suggestions"**: Turns on the `Did you mean '--myoption' ?` feature for when users make /// * **"suggestions"**: Turns on the `Did you mean '--myoption' ?` feature for when users make
/// typos. /// typos.
/// * **"color"**: Turns on red error messages. This feature only works on non-Windows OSs. /// * **"color"**: Turns on red error messages. This feature only works on non-Windows OSs.
/// * **"lints"**: This is **not** included by default and should only be used while developing to /// * **"lints"**: This is **not** included by default and should only be used while developing to
/// run basic lints against changes. This can only be used on Rust nightly. /// run basic lints against changes. This can only be used on Rust nightly.
/// ///
/// ### Dependencies Tree /// ### Dependencies Tree
/// ///
/// The following graphic depicts `clap`s dependency graph. /// The following graphic depicts `clap`s dependency graph.
/// ///
/// * **Dashed** Line: Optional dependency /// * **Dashed** Line: Optional dependency
/// * **Red** Color: **NOT** included by default (must use cargo `features` to enable) /// * **Red** Color: **NOT** included by default (must use cargo `features` to enable)
/// ///
/// ![clap dependencies](https://raw.githubusercontent.com/kbknapp/clap-rs/master/clap.png) /// ![clap dependencies](https://raw.githubusercontent.com/kbknapp/clap-rs/master/clap.png)
/// ///
/// ### More Information /// ### More Information
/// ///
/// You can find complete documentation on the [github-pages site](http://kbknapp.github.io/clap-rs/clap/index.html) /// You can find complete documentation on the [github-pages site](http://kbknapp.github.io/clap-rs/clap/index.html)
/// for this project. /// for this project.
/// ///
/// You can also find usage examples in the [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples) /// You can also find usage examples in the [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples)
/// directory of this repo. /// directory of this repo.
/// ///
/// #### Video Tutorials /// #### Video Tutorials
/// ///
/// There's also the video tutorial series [Argument Parsing with Rust](https://www.youtube.com/playlist?list=PLza5oFLQGTl0Bc_EU_pBNcX-rhVqDTRxv) /// There's also the video tutorial series [Argument Parsing with Rust](https://www.youtube.com/playlist?list=PLza5oFLQGTl0Bc_EU_pBNcX-rhVqDTRxv)
/// that I've been working on. /// that I've been working on.
/// ///
/// *Note*: Two new videos have just been added ([08 From Usage](https://youtu.be/xc6VdedFrG0), and /// *Note*: Two new videos have just been added ([08 From Usage](https://youtu.be/xc6VdedFrG0), and
/// [09 Typed Values](https://youtu.be/mZn3C1DnD90)), if you're already familiar with `clap` but /// [09 Typed Values](https://youtu.be/mZn3C1DnD90)), 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 /// want to know more about these two details you can check out those videos without watching the
/// previous few. /// previous few.
/// ///
/// *Note*: Apologies for the resolution of the first video, it will be updated to a better /// *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. /// resolution soon. The other videos have a proper resolution.
/// ///
/// ### Running the tests /// ### Running the tests
/// ///
/// If contributing, you can run the tests as follows (assuming you're in the `clap-rs` directory) /// If contributing, you can run the tests as follows (assuming you're in the `clap-rs` directory)
/// ///
/// ```ignore /// ```ignore
/// cargo test --features yaml && make -C clap-tests test /// cargo test --features yaml && make -C clap-tests test
/// ``` /// ```
/// ///
/// ## License /// ## License
/// ///
/// `clap` is licensed under the MIT license. Please read the [LICENSE-MIT](https://raw.githubusercontent.com/kbknapp/clap-rs/master/LICENSE-MIT) /// `clap` is licensed under the MIT license. Please read the [LICENSE-MIT](https://raw.githubusercontent.com/kbknapp/clap-rs/master/LICENSE-MIT)
/// file in /// file in
/// this repository for more information. /// this repository for more information.
/// ///
#[cfg(feature = "suggestions")] #[cfg(feature = "suggestions")]
extern crate strsim; extern crate strsim;