diff --git a/README.md b/README.md index ac617513b0a..c5109dcb9f7 100644 --- a/README.md +++ b/README.md @@ -371,34 +371,6 @@ fn main() { } ``` -#### 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. - -```rust,no_run -use clap::clap_app; - -fn main() { - let matches = clap_app!(myapp => - (version: "1.0") - (author: "Kevin K. ") - (about: "Does awesome things") - (@arg CONFIG: -c --config [FILE] "Sets a custom config file") - (@arg INPUT: +required "Sets the input file to use") - (@arg verbose: -v --verbose "Sets the level of verbosity") - (@subcommand test => - (about: "controls testing features") - (version: "1.3") - (author: "Someone E. ") - (@arg debug: -d --debug "Print debug 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). diff --git a/benches/03_complex.rs b/benches/03_complex.rs index 450cb808f9a..efb79e3da37 100644 --- a/benches/03_complex.rs +++ b/benches/03_complex.rs @@ -1,4 +1,4 @@ -use clap::{clap_app, App, AppSettings, Arg, ArgSettings}; +use clap::{App, AppSettings, Arg, ArgSettings}; use criterion::{criterion_group, criterion_main, Criterion}; static OPT3_VALS: [&str; 2] = ["fast", "slow"]; @@ -160,42 +160,6 @@ pub fn build_from_builder(c: &mut Criterion) { }); } -pub fn build_from_macros(c: &mut Criterion) { - c.bench_function("build_from_macros", |b| { - b.iter(|| { - clap_app!(claptests => - (version: "0.1") - (about: "tests clap library") - (author: "Kevin K. ") - (@arg opt: -o --option +takes_value ... "tests options") - (@arg positional: index(1) "tests positionals") - (@arg flag: -f --flag ... +global "tests flags") - (@arg flag2: -F conflicts_with[flag] requires[option2] - "tests flags with exclusions") - (@arg option2: --long_option_2 conflicts_with[option] requires[positional2] - "tests long options with exclusions") - (@arg positional2: index(2) "tests positionals with exclusions") - (@arg option3: -O --Option +takes_value possible_value[fast slow] - "tests options with specific value sets") - (@arg positional3: index(3) ... possible_value[vi emacs] - "tests positionals with specific values") - (@arg multvals: --multvals +takes_value value_name[one two] - "Tests multiple values, not mult occs") - (@arg multvalsmo: --multvalsmo ... +takes_value value_name[one two] - "Tests multiple values, not mult occs") - (@arg minvals: --minvals2 min_values(1) ... +takes_value "Tests 2 min vals") - (@arg maxvals: --maxvals3 ... +takes_value max_values(3) "Tests 3 max vals") - (@subcommand subcmd => - (about: "tests subcommands") - (version: "0.1") - (author: "Kevin K. ") - (@arg scoption: -o --option ... +takes_value "tests options") - (@arg scpositional: index(1) "tests positionals")) - ); - }) - }); -} - pub fn parse_complex(c: &mut Criterion) { c.bench_function("parse_complex", |b| { b.iter(|| create_app!().get_matches_from(vec![""])) @@ -327,7 +291,6 @@ criterion_group!( benches, build_from_usage, build_from_builder, - build_from_macros, parse_complex, parse_complex_with_flag, parse_complex_with_opt, diff --git a/examples/01c_quick_example.rs b/examples/01c_quick_example.rs deleted file mode 100644 index 5c1644e7bed..00000000000 --- a/examples/01c_quick_example.rs +++ /dev/null @@ -1,76 +0,0 @@ -use clap::clap_app; - -fn main() { - // This example shows how to create an application with several arguments using macro builder. - // It combines the simplicity of the from_usage methods and the performance of the Builder Pattern. - // - // The example below is functionally identical to the one in 01a_quick_example.rs and 01b_quick_example.rs - // - // Create an application with 5 possible arguments (2 auto generated) and 2 subcommands (1 auto generated) - // - A config file - // + Uses "-c filename" or "--config filename" - // - An output file - // + A positional argument (i.e. "$ myapp output_filename") - // - A debug flag - // + Uses "-d" or "--debug" - // + Allows multiple occurrences of such as "-dd" (for vary levels of debugging, as an example) - // - A help flag (automatically generated by clap) - // + Uses "-h" or "--help" (Only autogenerated if you do NOT specify your own "-h" or "--help") - // - A version flag (automatically generated by clap) - // + Uses "-V" or "--version" (Only autogenerated if you do NOT specify your own "-V" or "--version") - // - A subcommand "test" (subcommands behave like their own apps, with their own arguments - // + Used by "$ myapp test" with the following arguments - // > A list flag - // = Uses "-l" (usage is "$ myapp test -l" - // > A help flag (automatically generated by clap - // = Uses "-h" or "--help" (full usage "$ myapp test -h" or "$ myapp test --help") - // > A version flag (automatically generated by clap - // = Uses "-V" or "--version" (full usage "$ myapp test -V" or "$ myapp test --version") - // - A subcommand "help" (automatically generated by clap because we specified a subcommand of our own) - // + Used by "$ myapp help" (same functionality as "-h" or "--help") - let matches = clap_app!(myapp => - (version: "1.0") - (author: "Kevin K. ") - (about: "Does awesome things") - (license: "MIT OR Apache-2.0") - (@arg CONFIG: -c --config +takes_value "Sets a custom config file") - (@arg INPUT: +required "Sets the input file to use") - (@arg debug: -d ... "Sets the level of debugging information") - (@subcommand test => - (about: "controls testing features") - (version: "1.3") - (author: "Someone E. ") - (@arg verbose: -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"), - _ => 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 program logic goes here... -} diff --git a/examples/18_builder_macro.rs b/examples/18_builder_macro.rs deleted file mode 100644 index af54e68dedc..00000000000 --- a/examples/18_builder_macro.rs +++ /dev/null @@ -1,83 +0,0 @@ -use clap::clap_app; - -// Note, there isn't a need for "use clap::{ ... };" Because the clap_app! macro uses -// $crate:: internally - -fn main() { - // Validation example testing that a file exists - let file_exists = |path: &str| { - if std::fs::metadata(path).is_ok() { - Ok(()) - } else { - Err(String::from("File doesn't exist")) - } - }; - - // External module may contain this subcommand. If this exists in another module, a function is - // required to access it. Recommend `fn clap() -> clap::App`. - let external_sub_command = clap_app!( @subcommand foo => - (@arg bar: -b "Bar") - ); - - let matches = clap_app!(MyApp => - (@setting SubcommandRequiredElseHelp) - (version: "1.0") - (author: "Alice") - (license: "MIT OR Apache-2.0") - (about: "Does awesome things") - (@arg config: -c --config #{1, 2} {file_exists} "Sets a custom config file") - (@arg proxyHostname: --("proxy-hostname") +takes_value "Sets the hostname of the proxy to use") - (@arg input: * "Input file") - (@group test: - (@attributes +required) - (@arg output: "Sets an optional output file") - (@arg debug: -d ... "Turn debugging information on") - ) - (subcommand: external_sub_command) - (@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(); - - // You can check the value provided by positional arguments, or option arguments - if let Some(o) = matches.value_of("output") { - println!("Value for output: {}", o); - } - - 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("debug") { - 0 => println!("Debug mode is off"), - 1 => println!("Debug mode is kind of on"), - 2 => println!("Debug mode is on"), - _ => 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(matches) = matches.subcommand_matches("test") { - // "$ myapp test" was run - if matches.is_present("list") { - // "$ myapp test -l" was run - println!("Printing testing lists..."); - } else { - println!("Not printing testing lists..."); - } - } - - // Continued program logic goes here... -} diff --git a/src/macros.rs b/src/macros.rs index 723027e456b..85bf69eb728 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -295,6 +295,10 @@ macro_rules! app_from_crate { /// [`Arg::max_values(max)`]: crate::Arg::max_values() /// [`Arg::validator`]: crate::Arg::validator() /// [`Arg::conflicts_with`]: crate::Arg::conflicts_with() +#[deprecated( + since = "3.0.0", + note = "Replaced with `App` builder API (with `From::from` for parsing usage) or `Parser` derive API (Issue #2835)" +)] #[macro_export] macro_rules! clap_app { (@app ($builder:expr)) => { $builder }; diff --git a/tests/help.rs b/tests/help.rs index d1db65b79a4..a15d382252e 100644 --- a/tests/help.rs +++ b/tests/help.rs @@ -1,6 +1,6 @@ mod utils; -use clap::{clap_app, App, AppSettings, Arg, ArgGroup, ArgSettings, ArgValue, ErrorKind}; +use clap::{App, AppSettings, Arg, ArgGroup, ArgSettings, ArgValue, ErrorKind}; static REQUIRE_DELIM_HELP: &str = "test 1.3 @@ -707,11 +707,21 @@ fn help_subcommand() { #[test] fn req_last_arg_usage() { - let app = clap_app!(example => - (version: "1.0") - (@arg FIRST: ... * "First") - (@arg SECOND: ... * +last "Second") - ); + let app = App::new("example") + .version("1.0") + .arg( + Arg::new("FIRST") + .about("First") + .multiple_values(true) + .required(true), + ) + .arg( + Arg::new("SECOND") + .about("Second") + .multiple_values(true) + .required(true) + .last(true), + ); assert!(utils::compare_output( app, "example --help", diff --git a/tests/macros.rs b/tests/macros.rs index 1ce22fb5eeb..1bf90ebc281 100644 --- a/tests/macros.rs +++ b/tests/macros.rs @@ -27,6 +27,7 @@ SUBCOMMANDS: #[test] fn basic() { + #![allow(deprecated)] clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -61,6 +62,7 @@ fn basic() { #[test] fn quoted_app_name() { + #![allow(deprecated)] let mut app = clap::clap_app!(("app name with spaces-and-hyphens") => (version: "0.1") (about: "tests clap library") @@ -102,6 +104,7 @@ fn quoted_app_name() { #[test] fn quoted_arg_long_name() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -140,6 +143,7 @@ fn quoted_arg_long_name() { #[test] fn quoted_arg_name() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -178,6 +182,7 @@ fn quoted_arg_name() { #[test] fn quoted_subcommand_name() { + #![allow(deprecated)] clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -213,6 +218,7 @@ fn quoted_subcommand_name() { #[test] fn group_macro() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -233,6 +239,7 @@ fn group_macro() { #[test] fn group_macro_set_multiple() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -255,6 +262,7 @@ fn group_macro_set_multiple() { #[test] fn group_macro_set_not_multiple() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -274,6 +282,7 @@ fn group_macro_set_not_multiple() { #[test] fn group_macro_set_required() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -293,6 +302,7 @@ fn group_macro_set_required() { #[test] fn group_macro_set_not_required() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -312,6 +322,7 @@ fn group_macro_set_not_required() { #[test] fn group_macro_attributes_alternative() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -342,6 +353,7 @@ fn group_macro_attributes_alternative() { #[test] fn group_macro_multiple_methods() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -371,6 +383,7 @@ fn group_macro_multiple_methods() { #[test] fn group_macro_multiple_methods_alternative() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -400,6 +413,7 @@ fn group_macro_multiple_methods_alternative() { #[test] fn group_macro_multiple_invokations() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (version: "0.1") (about: "tests clap library") @@ -428,6 +442,7 @@ fn group_macro_multiple_invokations() { #[test] fn literals() { + #![allow(deprecated)] let app = clap::clap_app!("clap-tests" => (version: "0.1") (@arg "task-num": -"t-n" --"task-num" +takes_value possible_value["all" 0 1 2] @@ -453,6 +468,7 @@ fn literals() { #[test] fn multiarg() { + #![allow(deprecated)] let app = clap::clap_app!(claptests => (@arg flag: --flag "value") (@arg multiarg: --multiarg @@ -481,6 +497,8 @@ fn multiarg() { #[test] fn validator() { + #![allow(deprecated)] + use std::str::FromStr; fn validate(val: &str) -> Result {