diff options
Diffstat (limited to 'third_party/rust/clap/benches')
-rw-r--r-- | third_party/rust/clap/benches/01_default.rs | 15 | ||||
-rw-r--r-- | third_party/rust/clap/benches/02_simple.rs | 104 | ||||
-rw-r--r-- | third_party/rust/clap/benches/03_complex.rs | 307 | ||||
-rw-r--r-- | third_party/rust/clap/benches/04_new_help.rs | 223 | ||||
-rw-r--r-- | third_party/rust/clap/benches/05_ripgrep.rs | 952 | ||||
-rw-r--r-- | third_party/rust/clap/benches/06_rustup.rs | 412 |
6 files changed, 2013 insertions, 0 deletions
diff --git a/third_party/rust/clap/benches/01_default.rs b/third_party/rust/clap/benches/01_default.rs new file mode 100644 index 0000000000..620b32b818 --- /dev/null +++ b/third_party/rust/clap/benches/01_default.rs @@ -0,0 +1,15 @@ +use clap::Command; +use criterion::{criterion_group, criterion_main, Criterion}; + +pub fn build_empty(c: &mut Criterion) { + c.bench_function("build_empty", |b| b.iter(|| Command::new("claptests"))); +} + +pub fn parse_empty(c: &mut Criterion) { + c.bench_function("parse_empty", |b| { + b.iter(|| Command::new("claptests").get_matches_from(vec![""])) + }); +} + +criterion_group!(benches, build_empty, parse_empty); +criterion_main!(benches); diff --git a/third_party/rust/clap/benches/02_simple.rs b/third_party/rust/clap/benches/02_simple.rs new file mode 100644 index 0000000000..667d02f873 --- /dev/null +++ b/third_party/rust/clap/benches/02_simple.rs @@ -0,0 +1,104 @@ +use clap::{arg, Arg, Command}; +use criterion::{criterion_group, criterion_main, Criterion}; + +macro_rules! create_app { + () => {{ + Command::new("claptests") + .version("0.1") + .about("tests clap library") + .author("Kevin K. <kbknapp@gmail.com>") + .arg(arg!(-f --flag "tests flags")) + .arg(arg!(-o --option <opt> "tests options").required(false)) + .arg(arg!([positional] "tests positional")) + }}; +} + +pub fn build_simple(c: &mut Criterion) { + c.bench_function("build_simple", |b| b.iter(|| create_app!())); +} + +pub fn build_with_flag(c: &mut Criterion) { + c.bench_function("build_with_flag", |b| { + b.iter(|| Command::new("claptests").arg(arg!(-s --some "something"))) + }); +} + +pub fn build_with_flag_ref(c: &mut Criterion) { + c.bench_function("build_with_flag_ref", |b| { + b.iter(|| { + let arg = arg!(-s --some "something"); + Command::new("claptests").arg(&arg) + }) + }); +} + +pub fn build_with_opt(c: &mut Criterion) { + c.bench_function("build_with_opt", |b| { + b.iter(|| Command::new("claptests").arg(arg!(-s --some <FILE> "something"))) + }); +} + +pub fn build_with_opt_ref(c: &mut Criterion) { + c.bench_function("build_with_opt_ref", |b| { + b.iter(|| { + let arg = arg!(-s --some <FILE> "something"); + Command::new("claptests").arg(&arg) + }) + }); +} + +pub fn build_with_pos(c: &mut Criterion) { + c.bench_function("build_with_pos", |b| { + b.iter(|| Command::new("claptests").arg(Arg::new("some"))) + }); +} + +pub fn build_with_pos_ref(c: &mut Criterion) { + c.bench_function("build_with_pos_ref", |b| { + b.iter(|| { + let arg = Arg::new("some"); + Command::new("claptests").arg(&arg) + }) + }); +} + +pub fn parse_simple_with_flag(c: &mut Criterion) { + c.bench_function("parse_simple_with_flag", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "-f"])) + }); +} + +pub fn parse_simple_with_opt(c: &mut Criterion) { + c.bench_function("parse_simple_with_opt", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "-o", "option1"])) + }); +} + +pub fn parse_simple_with_pos(c: &mut Criterion) { + c.bench_function("parse_simple_with_pos", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "arg1"])) + }); +} + +pub fn parse_simple_with_complex(c: &mut Criterion) { + c.bench_function("parse_simple_with_complex", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "-o", "option1", "-f", "arg1"])) + }); +} + +criterion_group!( + benches, + parse_simple_with_complex, + parse_simple_with_pos, + parse_simple_with_opt, + parse_simple_with_flag, + build_with_pos_ref, + build_with_pos, + build_with_opt_ref, + build_with_opt, + build_with_flag_ref, + build_with_flag, + build_simple +); + +criterion_main!(benches); diff --git a/third_party/rust/clap/benches/03_complex.rs b/third_party/rust/clap/benches/03_complex.rs new file mode 100644 index 0000000000..3ac81bb15d --- /dev/null +++ b/third_party/rust/clap/benches/03_complex.rs @@ -0,0 +1,307 @@ +use clap::{arg, Arg, Command}; +use criterion::{criterion_group, criterion_main, Criterion}; + +static OPT3_VALS: [&str; 2] = ["fast", "slow"]; +static POS3_VALS: [&str; 2] = ["vi", "emacs"]; + +macro_rules! create_app { + () => {{ + Command::new("claptests") + .version("0.1") + .about("tests clap library") + .author("Kevin K. <kbknapp@gmail.com>") + .arg(arg!(-o --option <opt> ... "tests options").required(false)) + .arg(arg!([positional] "tests positionals")) + .arg(arg!(-f --flag ... "tests flags").global(true)) + .args(&[ + arg!(flag2: -F "tests flags with exclusions") + .conflicts_with("flag") + .requires("option2"), + arg!(option2: --"long-option-2" <option2> "tests long options with exclusions") + .required(false) + .conflicts_with("option") + .requires("positional2"), + arg!([positional2] "tests positionals with exclusions"), + arg!(-O --Option <option3> "tests options with specific value sets") + .required(false) + .possible_values(OPT3_VALS), + arg!([positional3] ... "tests positionals with specific values") + .possible_values(POS3_VALS), + arg!(--multvals "Tests multiple values not mult occs").required(false).value_names(&["one", "two"]), + arg!( + --multvalsmo "Tests multiple values, not mult occs" + ).multiple_values(true).required(false).value_names(&["one", "two"]), + arg!(--minvals2 <minvals> ... "Tests 2 min vals").min_values(2).multiple_values(true).required(false), + arg!(--maxvals3 <maxvals> ... "Tests 3 max vals").max_values(3).multiple_values(true).required(false), + ]) + .subcommand( + Command::new("subcmd") + .about("tests subcommands") + .version("0.1") + .author("Kevin K. <kbknapp@gmail.com>") + .arg(arg!(-o --option <scoption> ... "tests options").required(false)) + .arg(arg!([scpositional] "tests positionals")) + ) + }}; +} + +pub fn build_from_builder(c: &mut Criterion) { + c.bench_function("build_from_builder", |b| { + b.iter(|| { + Command::new("claptests") + .version("0.1") + .about("tests clap library") + .author("Kevin K. <kbknapp@gmail.com>") + .arg( + Arg::new("opt") + .help("tests options") + .short('o') + .long("option") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true), + ) + .arg(Arg::new("positional").help("tests positionals").index(1)) + .arg( + Arg::new("flag") + .short('f') + .help("tests flags") + .long("flag") + .global(true) + .multiple_occurrences(true), + ) + .arg( + Arg::new("flag2") + .short('F') + .help("tests flags with exclusions") + .conflicts_with("flag") + .requires("option2"), + ) + .arg( + Arg::new("option2") + .help("tests long options with exclusions") + .conflicts_with("option") + .requires("positional2") + .takes_value(true) + .long("long-option-2"), + ) + .arg( + Arg::new("positional2") + .index(3) + .help("tests positionals with exclusions"), + ) + .arg( + Arg::new("option3") + .short('O') + .long("Option") + .takes_value(true) + .help("tests options with specific value sets") + .possible_values(OPT3_VALS), + ) + .arg( + Arg::new("positional3") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true) + .help("tests positionals with specific values") + .index(4) + .possible_values(POS3_VALS), + ) + .arg( + Arg::new("multvals") + .long("multvals") + .help("Tests multiple values, not mult occs") + .value_names(&["one", "two"]), + ) + .arg( + Arg::new("multvalsmo") + .long("multvalsmo") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true) + .help("Tests multiple values, not mult occs") + .value_names(&["one", "two"]), + ) + .arg( + Arg::new("minvals") + .long("minvals2") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true) + .help("Tests 2 min vals") + .min_values(2), + ) + .arg( + Arg::new("maxvals") + .long("maxvals3") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true) + .help("Tests 3 max vals") + .max_values(3), + ) + .subcommand( + Command::new("subcmd") + .about("tests subcommands") + .version("0.1") + .author("Kevin K. <kbknapp@gmail.com>") + .arg( + Arg::new("scoption") + .short('o') + .long("option") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true) + .help("tests options"), + ) + .arg(Arg::new("scpositional").index(1).help("tests positionals")), + ) + }) + }); +} + +pub fn parse_complex(c: &mut Criterion) { + c.bench_function("parse_complex", |b| { + b.iter(|| create_app!().get_matches_from(vec![""])) + }); +} + +pub fn parse_complex_with_flag(c: &mut Criterion) { + c.bench_function("parse_complex_with_flag", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "-f"])) + }); +} + +pub fn parse_complex_with_opt(c: &mut Criterion) { + c.bench_function("parse_complex_with_opt", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "-o", "option1"])) + }); +} + +pub fn parse_complex_with_pos(c: &mut Criterion) { + c.bench_function("parse_complex_with_pos", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "arg1"])) + }); +} + +pub fn parse_complex_with_sc(c: &mut Criterion) { + c.bench_function("parse_complex_with_sc", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd"])) + }); +} + +pub fn parse_complex_with_sc_flag(c: &mut Criterion) { + c.bench_function("parse_complex_with_sc_flag", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-f"])) + }); +} + +pub fn parse_complex_with_sc_opt(c: &mut Criterion) { + c.bench_function("parse_complex_with_sc_opt", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-o", "option1"])) + }); +} + +pub fn parse_complex_with_sc_pos(c: &mut Criterion) { + c.bench_function("parse_complex_with_sc_pos", |b| { + b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "arg1"])) + }); +} + +pub fn parse_complex1(c: &mut Criterion) { + c.bench_function("parse_complex1", |b| { + b.iter(|| { + create_app!().get_matches_from(vec![ + "myprog", + "-ff", + "-o", + "option1", + "arg1", + "-O", + "fast", + "arg2", + "--multvals", + "one", + "two", + "emacs", + ]) + }) + }); +} + +pub fn parse_complex2(c: &mut Criterion) { + c.bench_function("parse_complex2", |b| { + b.iter(|| { + create_app!().get_matches_from(vec![ + "myprog", + "arg1", + "-f", + "arg2", + "--long-option-2", + "some", + "-O", + "slow", + "--multvalsmo", + "one", + "two", + "--minvals2", + "3", + "2", + "1", + ]) + }) + }); +} + +pub fn parse_args_negate_scs(c: &mut Criterion) { + c.bench_function("parse_args_negate_scs", |b| { + b.iter(|| { + create_app!() + .args_conflicts_with_subcommands(true) + .get_matches_from(vec![ + "myprog", + "arg1", + "-f", + "arg2", + "--long-option-2", + "some", + "-O", + "slow", + "--multvalsmo", + "one", + "two", + "--minvals2", + "3", + "2", + "1", + ]) + }) + }); +} + +pub fn parse_complex_with_sc_complex(c: &mut Criterion) { + c.bench_function("parse_complex_with_sc_complex", |b| { + b.iter(|| { + create_app!().get_matches_from(vec!["myprog", "subcmd", "-f", "-o", "option1", "arg1"]) + }) + }); +} + +criterion_group!( + benches, + build_from_builder, + parse_complex, + parse_complex_with_flag, + parse_complex_with_opt, + parse_complex_with_pos, + parse_complex_with_sc, + parse_complex_with_sc_flag, + parse_complex_with_sc_opt, + parse_complex_with_sc_pos, + parse_complex1, + parse_complex2, + parse_args_negate_scs, + parse_complex_with_sc_complex +); + +criterion_main!(benches); diff --git a/third_party/rust/clap/benches/04_new_help.rs b/third_party/rust/clap/benches/04_new_help.rs new file mode 100644 index 0000000000..83b14fb706 --- /dev/null +++ b/third_party/rust/clap/benches/04_new_help.rs @@ -0,0 +1,223 @@ +use clap::Command; +use clap::{arg, Arg}; +use criterion::{criterion_group, criterion_main, Criterion}; +use std::io::Cursor; + +fn build_help(cmd: &mut Command) -> String { + let mut buf = Cursor::new(Vec::with_capacity(50)); + cmd.write_help(&mut buf).unwrap(); + let content = buf.into_inner(); + String::from_utf8(content).unwrap() +} + +fn app_example1<'c>() -> Command<'c> { + Command::new("MyApp") + .version("1.0") + .author("Kevin K. <kbknapp@gmail.com>") + .about("Does awesome things") + .arg( + arg!( + -c --config <FILE> "Sets a custom config file" + ) + .required(false), + ) + .arg(arg!(<output> "Sets an optional output file")) + .arg(arg!(d: -d ... "Turn debugging information on")) + .subcommand( + Command::new("test") + .about("does testing things") + .arg(arg!(-l --list "lists test values")), + ) +} + +fn app_example2<'c>() -> Command<'c> { + Command::new("MyApp") + .version("1.0") + .author("Kevin K. <kbknapp@gmail.com>") + .about("Does awesome things") +} + +fn app_example3<'c>() -> Command<'c> { + Command::new("MyApp") + .arg( + Arg::new("debug") + .help("turn on debugging information") + .short('d'), + ) + .args(&[ + Arg::new("config") + .help("sets the config file to use") + .takes_value(true) + .short('c') + .long("config"), + Arg::new("input") + .help("the input file to use") + .required(true), + ]) + .arg(arg!(--license "display the license file")) + .arg(arg!([output] "Supply an output file to use")) + .arg( + arg!( + -i --int <IFACE> "Set an interface to use" + ) + .required(false), + ) +} + +fn app_example4<'c>() -> Command<'c> { + Command::new("MyApp") + .about("Parses an input file to do awesome things") + .version("1.0") + .author("Kevin K. <kbknapp@gmail.com>") + .arg( + Arg::new("debug") + .help("turn on debugging information") + .short('d') + .long("debug"), + ) + .arg( + Arg::new("config") + .help("sets the config file to use") + .short('c') + .long("config"), + ) + .arg( + Arg::new("input") + .help("the input file to use") + .index(1) + .required(true), + ) +} + +fn app_example5<'c>() -> Command<'c> { + Command::new("MyApp").arg( + Arg::new("awesome") + .help("turns up the awesome") + .short('a') + .long("awesome") + .multiple_occurrences(true), + ) +} + +fn app_example6<'c>() -> Command<'c> { + Command::new("MyApp") + .arg( + Arg::new("input") + .help("the input file to use") + .index(1) + .requires("config") + .required(true), + ) + .arg(Arg::new("config").help("the config file to use").index(2)) +} + +fn app_example7<'c>() -> Command<'c> { + Command::new("MyApp") + .arg(Arg::new("config")) + .arg(Arg::new("output")) + .arg( + Arg::new("input") + .help("the input file to use") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true) + .required(true) + .short('i') + .long("input") + .requires("config") + .conflicts_with("output"), + ) +} + +fn app_example8<'c>() -> Command<'c> { + Command::new("MyApp") + .arg(Arg::new("config")) + .arg(Arg::new("output")) + .arg( + Arg::new("input") + .help("the input file to use") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true) + .required(true) + .short('i') + .long("input") + .requires("config") + .conflicts_with("output"), + ) +} + +fn app_example10<'c>() -> Command<'c> { + Command::new("myapp").about("does awesome things").arg( + Arg::new("CONFIG") + .help("The config file to use (default is \"config.json\")") + .short('c') + .takes_value(true), + ) +} + +pub fn example1(c: &mut Criterion) { + let mut cmd = app_example1(); + c.bench_function("example1", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example2(c: &mut Criterion) { + let mut cmd = app_example2(); + c.bench_function("example2", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example3(c: &mut Criterion) { + let mut cmd = app_example3(); + c.bench_function("example3", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example4(c: &mut Criterion) { + let mut cmd = app_example4(); + c.bench_function("example4", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example5(c: &mut Criterion) { + let mut cmd = app_example5(); + c.bench_function("example5", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example6(c: &mut Criterion) { + let mut cmd = app_example6(); + c.bench_function("example6", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example7(c: &mut Criterion) { + let mut cmd = app_example7(); + c.bench_function("example7", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example8(c: &mut Criterion) { + let mut cmd = app_example8(); + c.bench_function("example8", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example10(c: &mut Criterion) { + let mut cmd = app_example10(); + c.bench_function("example10", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn example4_template(c: &mut Criterion) { + let mut cmd = app_example4().help_template("{bin} {version}\n{author}\n{about}\n\nUSAGE:\n {usage}\n\nOPTIONS:\n{options}\n\nARGS:\n{args}\n"); + c.bench_function("example4_template", |b| b.iter(|| build_help(&mut cmd))); +} + +criterion_group!( + benches, + example1, + example2, + example3, + example4, + example5, + example6, + example7, + example8, + example10, + example4_template +); + +criterion_main!(benches); diff --git a/third_party/rust/clap/benches/05_ripgrep.rs b/third_party/rust/clap/benches/05_ripgrep.rs new file mode 100644 index 0000000000..7d5cab6964 --- /dev/null +++ b/third_party/rust/clap/benches/05_ripgrep.rs @@ -0,0 +1,952 @@ +// Used to simulate a fairly large number of options/flags and parsing with thousands of positional +// args +// +// CLI used is adapted from ripgrep 48a8a3a691220f9e5b2b08f4051abe8655ea7e8a + +use clap::{Arg, Command}; +use criterion::{criterion_group, criterion_main, Criterion}; +use std::collections::HashMap; +use std::io::Cursor; + +use lazy_static::lazy_static; + +pub fn build_rg_with_short_help(c: &mut Criterion) { + c.bench_function("build_rg_with_short_help", |b| b.iter(app_short)); +} + +pub fn build_rg_with_long_help(c: &mut Criterion) { + c.bench_function("build_rg_with_long_help", |b| b.iter(app_long)); +} + +pub fn write_rg_short_help(c: &mut Criterion) { + let mut cmd = app_short(); + c.bench_function("write_rg_short_help", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn write_rg_long_help(c: &mut Criterion) { + let mut cmd = app_long(); + c.bench_function("write_rg_long_help", |b| b.iter(|| build_help(&mut cmd))); +} + +pub fn parse_rg(c: &mut Criterion) { + c.bench_function("parse_rg", |b| { + b.iter(|| app_short().get_matches_from(vec!["rg", "pat"])) + }); +} + +pub fn parse_rg_with_complex(c: &mut Criterion) { + c.bench_function("parse_rg_with_complex", |b| { + b.iter(|| { + app_short().get_matches_from(vec![ + "rg", + "pat", + "-cFlN", + "-pqr=some", + "--null", + "--no-filename", + "--no-messages", + "-SH", + "-C5", + "--follow", + "-e some", + ]) + }) + }); +} + +pub fn parse_rg_with_lots(c: &mut Criterion) { + c.bench_function("parse_rg_with_lots", |b| { + b.iter(|| { + app_short().get_matches_from(vec![ + "rg", "pat", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", + "some", "some", "some", "some", "some", "some", + ]) + }) + }); +} + +const ABOUT: &str = " +ripgrep (rg) recursively searches your current directory for a regex pattern. + +ripgrep's regex engine uses finite automata and guarantees linear time +searching. Because of this, features like backreferences and arbitrary +lookaround are not supported. + +Project home page: https://github.com/BurntSushi/ripgrep + +Use -h for short descriptions and --help for more details."; + +const USAGE: &str = " + rg [OPTIONS] <pattern> [<path> ...] + rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...] + rg [OPTIONS] --files [<path> ...] + rg [OPTIONS] --type-list"; + +const TEMPLATE: &str = "\ +{bin} {version} +{author} +{about} + +USAGE:{usage} + +ARGS: +{positionals} + +OPTIONS: +{options}"; + +/// Build a clap application with short help strings. +fn app_short() -> Command<'static> { + cmd(false, |k| USAGES[k].short) +} + +/// Build a clap application with long help strings. +fn app_long() -> Command<'static> { + cmd(true, |k| USAGES[k].long) +} + +/// Build the help text of an application. +fn build_help(cmd: &mut Command) -> String { + let mut buf = Cursor::new(Vec::with_capacity(50)); + cmd.write_help(&mut buf).unwrap(); + let content = buf.into_inner(); + String::from_utf8(content).unwrap() +} + +/// Build a clap application parameterized by usage strings. +/// +/// The function given should take a clap argument name and return a help +/// string. `cmd` will panic if a usage string is not defined. +/// +/// This is an intentionally stand-alone module so that it can be used easily +/// in a `build.rs` script to build shell completion files. +fn cmd<F>(_next_line_help: bool, doc: F) -> Command<'static> +where + F: Fn(&'static str) -> &'static str, +{ + let arg = |name| Arg::new(name).help(doc(name)); + let flag = |name| arg(name).long(name); + + Command::new("ripgrep") + .author("BurntSushi") // simulating since it's only a bench + .version("0.4.0") // Simulating + .about(ABOUT) + .max_term_width(100) + .override_usage(USAGE) + .help_template(TEMPLATE) + // Handle help/version manually to make their output formatting + // consistent with short/long views. + .arg(arg("help-short").short('h')) + .arg(flag("help")) + .arg(flag("version").short('V')) + // First, set up primary positional/flag arguments. + .arg(arg("pattern").required_unless_present_any(&[ + "file", + "files", + "help-short", + "help", + "regexp", + "type-list", + "version", + ])) + .arg( + arg("path") + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true), + ) + .arg( + flag("regexp") + .short('e') + .allow_hyphen_values(true) + .multiple_occurrences(true) + .takes_value(true) + .value_name("pattern"), + ) + .arg( + flag("files") + // This should also conflict with `pattern`, but the first file + // path will actually be in `pattern`. + .conflicts_with_all(&["file", "regexp", "type-list"]), + ) + .arg(flag("type-list").conflicts_with_all(&["file", "files", "pattern", "regexp"])) + // Second, set up common flags. + .arg(flag("text").short('a')) + .arg(flag("count").short('c')) + .arg( + flag("color") + .value_name("WHEN") + .takes_value(true) + .hide_possible_values(true) + .possible_values(["never", "auto", "always", "ansi"]), + ) + .arg( + flag("colors") + .value_name("SPEC") + .multiple_occurrences(true) + .takes_value(true), + ) + .arg(flag("fixed-strings").short('F')) + .arg( + flag("glob") + .short('g') + .multiple_occurrences(true) + .takes_value(true) + .value_name("GLOB"), + ) + .arg(flag("ignore-case").short('i')) + .arg(flag("line-number").short('n')) + .arg(flag("no-line-number").short('N')) + .arg(flag("quiet").short('q')) + .arg( + flag("type") + .short('t') + .multiple_occurrences(true) + .takes_value(true) + .value_name("TYPE"), + ) + .arg( + flag("type-not") + .short('T') + .multiple_occurrences(true) + .takes_value(true) + .value_name("TYPE"), + ) + .arg(flag("unrestricted").short('u').multiple_occurrences(true)) + .arg(flag("invert-match").short('v')) + .arg(flag("word-regexp").short('w')) + // Third, set up less common flags. + .arg( + flag("after-context") + .short('A') + .value_name("NUM") + .validator(validate_number), + ) + .arg( + flag("before-context") + .short('B') + .value_name("NUM") + .validator(validate_number), + ) + .arg( + flag("context") + .short('C') + .value_name("NUM") + .validator(validate_number), + ) + .arg(flag("column")) + .arg(flag("context-separator").value_name("SEPARATOR")) + .arg(flag("debug")) + .arg( + flag("file") + .short('f') + .value_name("FILE") + .multiple_occurrences(true), + ) + .arg(flag("files-with-matches").short('l')) + .arg(flag("files-without-match")) + .arg(flag("with-filename").short('H')) + .arg(flag("no-filename")) + .arg(flag("heading").overrides_with("no-heading")) + .arg(flag("no-heading").overrides_with("heading")) + .arg(flag("hidden")) + .arg( + flag("ignore-file") + .value_name("FILE") + .multiple_occurrences(true), + ) + .arg(flag("follow").short('L')) + .arg( + flag("max-count") + .short('m') + .value_name("NUM") + .validator(validate_number), + ) + .arg( + flag("maxdepth") + .value_name("NUM") + .validator(validate_number), + ) + .arg(flag("mmap")) + .arg(flag("no-messages")) + .arg(flag("no-mmap")) + .arg(flag("no-ignore")) + .arg(flag("no-ignore-parent")) + .arg(flag("no-ignore-vcs")) + .arg(flag("null")) + .arg(flag("path-separator").value_name("SEPARATOR")) + .arg(flag("pretty").short('p')) + .arg(flag("replace").short('r').value_name("ARG")) + .arg(flag("case-sensitive").short('s')) + .arg(flag("smart-case").short('S')) + .arg(flag("sort-files")) + .arg( + flag("threads") + .short('j') + .value_name("ARG") + .validator(validate_number), + ) + .arg(flag("vimgrep")) + .arg( + flag("type-add") + .value_name("TYPE") + .multiple_occurrences(true), + ) + .arg( + flag("type-clear") + .value_name("TYPE") + .multiple_occurrences(true), + ) +} + +struct Usage { + short: &'static str, + long: &'static str, +} + +macro_rules! doc { + ($map:expr, $name:expr, $short:expr) => { + doc!($map, $name, $short, $short) + }; + ($map:expr, $name:expr, $short:expr, $long:expr) => { + $map.insert( + $name, + Usage { + short: $short, + long: concat!($long, "\n "), + }, + ); + }; +} + +lazy_static! { + static ref USAGES: HashMap<&'static str, Usage> = { + let mut h = HashMap::new(); + doc!( + h, + "help-short", + "Show short help output.", + "Show short help output. Use --help to show more details." + ); + doc!( + h, + "help", + "Show verbose help output.", + "When given, more details about flags are provided." + ); + doc!(h, "version", "Print version information."); + + doc!( + h, + "pattern", + "A regular expression used for searching.", + "A regular expression used for searching. Multiple patterns \ + may be given. To match a pattern beginning with a -, use [-]." + ); + doc!( + h, + "regexp", + "A regular expression used for searching.", + "A regular expression used for searching. Multiple patterns \ + may be given. To match a pattern beginning with a -, use [-]." + ); + doc!( + h, + "path", + "A file or directory to search.", + "A file or directory to search. Directories are searched \ + recursively." + ); + doc!( + h, + "files", + "Print each file that would be searched.", + "Print each file that would be searched without actually \ + performing the search. This is useful to determine whether a \ + particular file is being searched or not." + ); + doc!( + h, + "type-list", + "Show all supported file types.", + "Show all supported file types and their corresponding globs." + ); + + doc!(h, "text", "Search binary files as if they were text."); + doc!(h, "count", "Only show count of matches for each file."); + doc!( + h, + "color", + "When to use color. [default: auto]", + "When to use color in the output. The possible values are \ + never, auto, always or ansi. The default is auto. When always \ + is used, coloring is attempted based on your environment. When \ + ansi used, coloring is forcefully done using ANSI escape color \ + codes." + ); + doc!( + h, + "colors", + "Configure color settings and styles.", + "This flag specifies color settings for use in the output. \ + This flag may be provided multiple times. Settings are applied \ + iteratively. Colors are limited to one of eight choices: \ + red, blue, green, cyan, magenta, yellow, white and black. \ + Styles are limited to nobold, bold, nointense or intense.\n\n\ + The format of the flag is {type}:{attribute}:{value}. {type} \ + should be one of path, line or match. {attribute} can be fg, bg \ + or style. {value} is either a color (for fg and bg) or a text \ + style. A special format, {type}:none, will clear all color \ + settings for {type}.\n\nFor example, the following command will \ + change the match color to magenta and the background color for \ + line numbers to yellow:\n\n\ + rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo." + ); + doc!( + h, + "fixed-strings", + "Treat the pattern as a literal string.", + "Treat the pattern as a literal string instead of a regular \ + expression. When this flag is used, special regular expression \ + meta characters such as (){}*+. do not need to be escaped." + ); + doc!( + h, + "glob", + "Include or exclude files/directories.", + "Include or exclude files/directories for searching that \ + match the given glob. This always overrides any other \ + ignore logic. Multiple glob flags may be used. Globbing \ + rules match .gitignore globs. Precede a glob with a ! \ + to exclude it." + ); + doc!( + h, + "ignore-case", + "Case insensitive search.", + "Case insensitive search. This is overridden by \ + --case-sensitive." + ); + doc!( + h, + "line-number", + "Show line numbers.", + "Show line numbers (1-based). This is enabled by default when \ + searching in a tty." + ); + doc!( + h, + "no-line-number", + "Suppress line numbers.", + "Suppress line numbers. This is enabled by default when NOT \ + searching in a tty." + ); + doc!( + h, + "quiet", + "Do not print anything to stdout.", + "Do not print anything to stdout. If a match is found in a file, \ + stop searching. This is useful when ripgrep is used only for \ + its exit code." + ); + doc!( + h, + "type", + "Only search files matching TYPE.", + "Only search files matching TYPE. Multiple type flags may be \ + provided. Use the --type-list flag to list all available \ + types." + ); + doc!( + h, + "type-not", + "Do not search files matching TYPE.", + "Do not search files matching TYPE. Multiple type-not flags may \ + be provided. Use the --type-list flag to list all available \ + types." + ); + doc!( + h, + "unrestricted", + "Reduce the level of \"smart\" searching.", + "Reduce the level of \"smart\" searching. A single -u \ + won't respect .gitignore (etc.) files. Two -u flags will \ + additionally search hidden files and directories. Three \ + -u flags will additionally search binary files. -uu is \ + roughly equivalent to grep -r and -uuu is roughly \ + equivalent to grep -a -r." + ); + doc!( + h, + "invert-match", + "Invert matching.", + "Invert matching. Show lines that don't match given patterns." + ); + doc!( + h, + "word-regexp", + "Only show matches surrounded by word boundaries.", + "Only show matches surrounded by word boundaries. This is \ + equivalent to putting \\b before and after all of the search \ + patterns." + ); + + doc!(h, "after-context", "Show NUM lines after each match."); + doc!(h, "before-context", "Show NUM lines before each match."); + doc!(h, "context", "Show NUM lines before and after each match."); + doc!( + h, + "column", + "Show column numbers", + "Show column numbers (1-based). This only shows the column \ + numbers for the first match on each line. This does not try \ + to account for Unicode. One byte is equal to one column. This \ + implies --line-number." + ); + doc!( + h, + "context-separator", + "Set the context separator string. [default: --]", + "The string used to separate non-contiguous context lines in the \ + output. Escape sequences like \\x7F or \\t may be used. The \ + default value is --." + ); + doc!( + h, + "debug", + "Show debug messages.", + "Show debug messages. Please use this when filing a bug report." + ); + doc!( + h, + "file", + "Search for patterns from the given file.", + "Search for patterns from the given file, with one pattern per \ + line. When this flag is used or multiple times or in \ + combination with the -e/--regexp flag, then all patterns \ + provided are searched. Empty pattern lines will match all input \ + lines, and the newline is not counted as part of the pattern." + ); + doc!( + h, + "files-with-matches", + "Only show the path of each file with at least one match." + ); + doc!( + h, + "files-without-match", + "Only show the path of each file that contains zero matches." + ); + doc!( + h, + "with-filename", + "Show file name for each match.", + "Prefix each match with the file name that contains it. This is \ + the default when more than one file is searched." + ); + doc!( + h, + "no-filename", + "Never show the file name for a match.", + "Never show the file name for a match. This is the default when \ + one file is searched." + ); + doc!( + h, + "heading", + "Show matches grouped by each file.", + "This shows the file name above clusters of matches from each \ + file instead of showing the file name for every match. This is \ + the default mode at a tty." + ); + doc!( + h, + "no-heading", + "Don't group matches by each file.", + "Don't group matches by each file. If -H/--with-filename is \ + enabled, then file names will be shown for every line matched. \ + This is the default mode when not at a tty." + ); + doc!( + h, + "hidden", + "Search hidden files and directories.", + "Search hidden files and directories. By default, hidden files \ + and directories are skipped." + ); + doc!( + h, + "ignore-file", + "Specify additional ignore files.", + "Specify additional ignore files for filtering file paths. \ + Ignore files should be in the gitignore format and are matched \ + relative to the current working directory. These ignore files \ + have lower precedence than all other ignore files. When \ + specifying multiple ignore files, earlier files have lower \ + precedence than later files." + ); + doc!(h, "follow", "Follow symbolic links."); + doc!( + h, + "max-count", + "Limit the number of matches.", + "Limit the number of matching lines per file searched to NUM." + ); + doc!( + h, + "maxdepth", + "Descend at most NUM directories.", + "Limit the depth of directory traversal to NUM levels beyond \ + the paths given. A value of zero only searches the \ + starting-points themselves.\n\nFor example, \ + 'rg --maxdepth 0 dir/' is a no-op because dir/ will not be \ + descended into. 'rg --maxdepth 1 dir/' will search only the \ + direct children of dir/." + ); + doc!( + h, + "mmap", + "Searching using memory maps when possible.", + "Search using memory maps when possible. This is enabled by \ + default when ripgrep thinks it will be faster. Note that memory \ + map searching doesn't currently support all options, so if an \ + incompatible option (e.g., --context) is given with --mmap, \ + then memory maps will not be used." + ); + doc!( + h, + "no-messages", + "Suppress all error messages.", + "Suppress all error messages. This is equivalent to redirecting \ + stderr to /dev/null." + ); + doc!( + h, + "no-mmap", + "Never use memory maps.", + "Never use memory maps, even when they might be faster." + ); + doc!( + h, + "no-ignore", + "Don't respect ignore files.", + "Don't respect ignore files (.gitignore, .ignore, etc.). This \ + implies --no-ignore-parent and --no-ignore-vcs." + ); + doc!( + h, + "no-ignore-parent", + "Don't respect ignore files in parent directories.", + "Don't respect ignore files (.gitignore, .ignore, etc.) in \ + parent directories." + ); + doc!( + h, + "no-ignore-vcs", + "Don't respect VCS ignore files", + "Don't respect version control ignore files (.gitignore, etc.). \ + This implies --no-ignore-parent. Note that .ignore files will \ + continue to be respected." + ); + doc!( + h, + "null", + "Print NUL byte after file names", + "Whenever a file name is printed, follow it with a NUL byte. \ + This includes printing file names before matches, and when \ + printing a list of matching files such as with --count, \ + --files-with-matches and --files. This option is useful for use \ + with xargs." + ); + doc!( + h, + "path-separator", + "Path separator to use when printing file paths.", + "The path separator to use when printing file paths. This \ + defaults to your platform's path separator, which is / on Unix \ + and \\ on Windows. This flag is intended for overriding the \ + default when the environment demands it (e.g., cygwin). A path \ + separator is limited to a single byte." + ); + doc!(h, "pretty", "Alias for --color always --heading -n."); + doc!( + h, + "replace", + "Replace matches with string given.", + "Replace every match with the string given when printing \ + results. Neither this flag nor any other flag will modify your \ + files.\n\nCapture group indices (e.g., $5) and names \ + (e.g., $foo) are supported in the replacement string.\n\n\ + Note that the replacement by default replaces each match, and \ + NOT the entire line. To replace the entire line, you should \ + match the entire line." + ); + doc!( + h, + "case-sensitive", + "Search case sensitively.", + "Search case sensitively. This overrides -i/--ignore-case and \ + -S/--smart-case." + ); + doc!( + h, + "smart-case", + "Smart case search.", + "Searches case insensitively if the pattern is all lowercase. \ + Search case sensitively otherwise. This is overridden by \ + either -s/--case-sensitive or -i/--ignore-case." + ); + doc!( + h, + "sort-files", + "Sort results by file path. Implies --threads=1.", + "Sort results by file path. Note that this currently \ + disables all parallelism and runs search in a single thread." + ); + doc!( + h, + "threads", + "The approximate number of threads to use.", + "The approximate number of threads to use. A value of 0 (which \ + is the default) causes ripgrep to choose the thread count \ + using heuristics." + ); + doc!( + h, + "vimgrep", + "Show results in vim compatible format.", + "Show results with every match on its own line, including \ + line numbers and column numbers. With this option, a line with \ + more than one match will be printed more than once." + ); + + doc!( + h, + "type-add", + "Add a new glob for a file type.", + "Add a new glob for a particular file type. Only one glob can be \ + added at a time. Multiple --type-add flags can be provided. \ + Unless --type-clear is used, globs are added to any existing \ + globs defined inside of ripgrep.\n\nNote that this MUST be \ + passed to every invocation of ripgrep. Type settings are NOT \ + persisted.\n\nExample: \ + rg --type-add 'foo:*.foo' -tfoo PATTERN.\n\n\ + --type-add can also be used to include rules from other types \ + with the special include directive. The include directive \ + permits specifying one or more other type names (separated by a \ + comma) that have been defined and its rules will automatically \ + be imported into the type specified. For example, to create a \ + type called src that matches C++, Python and Markdown files, one \ + can use:\n\n\ + --type-add 'src:include:cpp,py,md'\n\n\ + Additional glob rules can still be added to the src type by \ + using the --type-add flag again:\n\n\ + --type-add 'src:include:cpp,py,md' --type-add 'src:*.foo'\n\n\ + Note that type names must consist only of Unicode letters or \ + numbers. Punctuation characters are not allowed." + ); + doc!( + h, + "type-clear", + "Clear globs for given file type.", + "Clear the file type globs previously defined for TYPE. This \ + only clears the default type definitions that are found inside \ + of ripgrep.\n\nNote that this MUST be passed to every \ + invocation of ripgrep. Type settings are NOT persisted." + ); + + h + }; +} + +fn validate_number(s: &str) -> Result<(), String> { + s.parse::<usize>() + .map(|_| ()) + .map_err(|err| err.to_string()) +} + +criterion_group!( + benches, + build_rg_with_short_help, + build_rg_with_long_help, + write_rg_short_help, + write_rg_long_help, + parse_rg, + parse_rg_with_complex, + parse_rg_with_lots +); +criterion_main!(benches); diff --git a/third_party/rust/clap/benches/06_rustup.rs b/third_party/rust/clap/benches/06_rustup.rs new file mode 100644 index 0000000000..8d9c406e40 --- /dev/null +++ b/third_party/rust/clap/benches/06_rustup.rs @@ -0,0 +1,412 @@ +// Used to simulate a fairly large number of subcommands +// +// CLI used is from rustup 408ed84f0e50511ed44a405dd91365e5da588790 + +use clap::{AppSettings, Arg, ArgGroup, Command}; +use criterion::{criterion_group, criterion_main, Criterion}; + +pub fn build_rustup(c: &mut Criterion) { + c.bench_function("build_rustup", |b| b.iter(build_cli)); +} + +pub fn parse_rustup(c: &mut Criterion) { + c.bench_function("parse_rustup", |b| { + b.iter(|| build_cli().get_matches_from(vec![""])) + }); +} + +pub fn parse_rustup_with_sc(c: &mut Criterion) { + c.bench_function("parse_rustup_with_sc", |b| { + b.iter(|| build_cli().get_matches_from(vec!["rustup override add stable"])) + }); +} + +fn build_cli() -> Command<'static> { + Command::new("rustup") + .version("0.9.0") // Simulating + .about("The Rust toolchain installer") + .after_help(RUSTUP_HELP) + .setting(AppSettings::DeriveDisplayOrder) + // .setting(AppSettings::SubcommandRequiredElseHelp) + .arg( + Arg::new("verbose") + .help("Enable verbose output") + .short('v') + .long("verbose"), + ) + .subcommand( + Command::new("show") + .about("Show the active and installed toolchains") + .after_help(SHOW_HELP), + ) + .subcommand( + Command::new("install") + .about("Update Rust toolchains") + .after_help(TOOLCHAIN_INSTALL_HELP) + .hide(true) // synonym for 'toolchain install' + .arg(Arg::new("toolchain").required(true)), + ) + .subcommand( + Command::new("update") + .about("Update Rust toolchains") + .after_help(UPDATE_HELP) + .arg(Arg::new("toolchain").required(true)) + .arg( + Arg::new("no-self-update") + .help("Don't perform self update when running the `rustup` command") + .long("no-self-update") + .hide(true), + ), + ) + .subcommand( + Command::new("default") + .about("Set the default toolchain") + .after_help(DEFAULT_HELP) + .arg(Arg::new("toolchain").required(true)), + ) + .subcommand( + Command::new("toolchain") + .about("Modify or query the installed toolchains") + .after_help(TOOLCHAIN_HELP) + .setting(AppSettings::DeriveDisplayOrder) + // .setting(AppSettings::SubcommandRequiredElseHelp) + .subcommand(Command::new("list").about("List installed toolchains")) + .subcommand( + Command::new("install") + .about("Install or update a given toolchain") + .arg(Arg::new("toolchain").required(true)), + ) + .subcommand( + Command::new("uninstall") + .about("Uninstall a toolchain") + .arg(Arg::new("toolchain").required(true)), + ) + .subcommand( + Command::new("link") + .about("Create a custom toolchain by symlinking to a directory") + .arg(Arg::new("toolchain").required(true)) + .arg(Arg::new("path").required(true)), + ) + .subcommand( + Command::new("update") + .hide(true) // synonym for 'install' + .arg(Arg::new("toolchain").required(true)), + ) + .subcommand( + Command::new("add") + .hide(true) // synonym for 'install' + .arg(Arg::new("toolchain").required(true)), + ) + .subcommand( + Command::new("remove") + .hide(true) // synonym for 'uninstall' + .arg(Arg::new("toolchain").required(true)), + ), + ) + .subcommand( + Command::new("target") + .about("Modify a toolchain's supported targets") + .setting(AppSettings::DeriveDisplayOrder) + // .setting(AppSettings::SubcommandRequiredElseHelp) + .subcommand( + Command::new("list") + .about("List installed and available targets") + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)), + ) + .subcommand( + Command::new("add") + .about("Add a target to a Rust toolchain") + .arg(Arg::new("target").required(true)) + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)), + ) + .subcommand( + Command::new("remove") + .about("Remove a target from a Rust toolchain") + .arg(Arg::new("target").required(true)) + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)), + ) + .subcommand( + Command::new("install") + .hide(true) // synonym for 'add' + .arg(Arg::new("target").required(true)) + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)), + ) + .subcommand( + Command::new("uninstall") + .hide(true) // synonym for 'remove' + .arg(Arg::new("target").required(true)) + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)), + ), + ) + .subcommand( + Command::new("component") + .about("Modify a toolchain's installed components") + .setting(AppSettings::DeriveDisplayOrder) + // .setting(AppSettings::SubcommandRequiredElseHelp) + .subcommand( + Command::new("list") + .about("List installed and available components") + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)), + ) + .subcommand( + Command::new("add") + .about("Add a component to a Rust toolchain") + .arg(Arg::new("component").required(true)) + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)) + .arg(Arg::new("target").long("target").takes_value(true)), + ) + .subcommand( + Command::new("remove") + .about("Remove a component from a Rust toolchain") + .arg(Arg::new("component").required(true)) + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)) + .arg(Arg::new("target").long("target").takes_value(true)), + ), + ) + .subcommand( + Command::new("override") + .about("Modify directory toolchain overrides") + .after_help(OVERRIDE_HELP) + .setting(AppSettings::DeriveDisplayOrder) + // .setting(AppSettings::SubcommandRequiredElseHelp) + .subcommand(Command::new("list").about("List directory toolchain overrides")) + .subcommand( + Command::new("set") + .about("Set the override toolchain for a directory") + .arg(Arg::new("toolchain").required(true)), + ) + .subcommand( + Command::new("unset") + .about("Remove the override toolchain for a directory") + .after_help(OVERRIDE_UNSET_HELP) + .arg( + Arg::new("path") + .long("path") + .takes_value(true) + .help("Path to the directory"), + ) + .arg( + Arg::new("nonexistent") + .long("nonexistent") + .help("Remove override toolchain for all nonexistent directories"), + ), + ) + .subcommand( + Command::new("add") + .hide(true) // synonym for 'set' + .arg(Arg::new("toolchain").required(true)), + ) + .subcommand( + Command::new("remove") + .hide(true) // synonym for 'unset' + .about("Remove the override toolchain for a directory") + .arg(Arg::new("path").long("path").takes_value(true)) + .arg( + Arg::new("nonexistent") + .long("nonexistent") + .help("Remove override toolchain for all nonexistent directories"), + ), + ), + ) + .subcommand( + Command::new("run") + .about("Run a command with an environment configured for a given toolchain") + .after_help(RUN_HELP) + .trailing_var_arg(true) + .arg(Arg::new("toolchain").required(true)) + .arg( + Arg::new("command") + .required(true) + .takes_value(true) + .multiple_values(true) + .multiple_occurrences(true), + ), + ) + .subcommand( + Command::new("which") + .about("Display which binary will be run for a given command") + .arg(Arg::new("command").required(true)), + ) + .subcommand( + Command::new("doc") + .about("Open the documentation for the current toolchain") + .after_help(DOC_HELP) + .arg( + Arg::new("book") + .long("book") + .help("The Rust Programming Language book"), + ) + .arg( + Arg::new("std") + .long("std") + .help("Standard library API documentation"), + ) + .group(ArgGroup::new("page").args(&["book", "std"])), + ) + .subcommand( + Command::new("man") + .about("View the man page for a given command") + .arg(Arg::new("command").required(true)) + .arg(Arg::new("toolchain").long("toolchain").takes_value(true)), + ) + .subcommand( + Command::new("self") + .about("Modify the rustup installation") + .setting(AppSettings::DeriveDisplayOrder) + .subcommand(Command::new("update").about("Download and install updates to rustup")) + .subcommand( + Command::new("uninstall") + .about("Uninstall rustup.") + .arg(Arg::new("no-prompt").short('y')), + ) + .subcommand( + Command::new("upgrade-data").about("Upgrade the internal data format."), + ), + ) + .subcommand( + Command::new("telemetry") + .about("rustup telemetry commands") + .hide(true) + .setting(AppSettings::DeriveDisplayOrder) + .subcommand(Command::new("enable").about("Enable rustup telemetry")) + .subcommand(Command::new("disable").about("Disable rustup telemetry")) + .subcommand(Command::new("analyze").about("Analyze stored telemetry")), + ) + .subcommand( + Command::new("set") + .about("Alter rustup settings") + .subcommand( + Command::new("default-host") + .about("The triple used to identify toolchains when not specified") + .arg(Arg::new("host_triple").required(true)), + ), + ) +} + +static RUSTUP_HELP: &str = r" +rustup installs The Rust Programming Language from the official +release channels, enabling you to easily switch between stable, beta, +and nightly compilers and keep them updated. It makes cross-compiling +simpler with binary builds of the standard library for common platforms. + +If you are new to Rust consider running `rustup doc --book` +to learn Rust."; + +static SHOW_HELP: &str = r" +Shows the name of the active toolchain and the version of `rustc`. + +If the active toolchain has installed support for additional +compilation targets, then they are listed as well. + +If there are multiple toolchains installed then all installed +toolchains are listed as well."; + +static UPDATE_HELP: &str = r" +With no toolchain specified, the `update` command updates each of the +installed toolchains from the official release channels, then updates +rustup itself. + +If given a toolchain argument then `update` updates that toolchain, +the same as `rustup toolchain install`. + +'toolchain' specifies a toolchain name, such as 'stable', 'nightly', +or '1.8.0'. For more information see `rustup help toolchain`."; + +static TOOLCHAIN_INSTALL_HELP: &str = r" +Installs a specific rust toolchain. + +The 'install' command is an alias for 'rustup update <toolchain>'. + +'toolchain' specifies a toolchain name, such as 'stable', 'nightly', +or '1.8.0'. For more information see `rustup help toolchain`."; + +static DEFAULT_HELP: &str = r" +Sets the default toolchain to the one specified. If the toolchain is +not already installed then it is installed first."; + +static TOOLCHAIN_HELP: &str = r" +Many `rustup` commands deal with *toolchains*, a single installation +of the Rust compiler. `rustup` supports multiple types of +toolchains. The most basic track the official release channels: +'stable', 'beta' and 'nightly'; but `rustup` can also install +toolchains from the official archives, for alternate host platforms, +and from local builds. + +Standard release channel toolchain names have the following form: + + <channel>[-<date>][-<host>] + + <channel> = stable|beta|nightly|<version> + <date> = YYYY-MM-DD + <host> = <target-triple> + +'channel' is either a named release channel or an explicit version +number, such as '1.8.0'. Channel names can be optionally appended with +an archive date, as in 'nightly-2014-12-18', in which case the +toolchain is downloaded from the archive for that date. + +Finally, the host may be specified as a target triple. This is most +useful for installing a 32-bit compiler on a 64-bit platform, or for +installing the [MSVC-based toolchain] on Windows. For example: + + rustup toolchain install stable-x86_64-pc-windows-msvc + +For convenience, elements of the target triple that are omitted will be +inferred, so the above could be written: + + $ rustup default stable-msvc + +Toolchain names that don't name a channel instead can be used to name +custom toolchains with the `rustup toolchain link` command."; + +static OVERRIDE_HELP: &str = r" +Overrides configure rustup to use a specific toolchain when +running in a specific directory. + +Directories can be assigned their own Rust toolchain with +`rustup override`. When a directory has an override then +any time `rustc` or `cargo` is run inside that directory, +or one of its child directories, the override toolchain +will be invoked. + +To pin to a specific nightly: + + rustup override set nightly-2014-12-18 + +Or a specific stable release: + + rustup override set 1.0.0 + +To see the active toolchain use `rustup show`. To remove the override +and use the default toolchain again, `rustup override unset`."; + +static OVERRIDE_UNSET_HELP: &str = r" +If `--path` argument is present, removes the override toolchain for +the specified directory. If `--nonexistent` argument is present, removes +the override toolchain for all nonexistent directories. Otherwise, +removes the override toolchain for the current directory."; + +static RUN_HELP: &str = r" +Configures an environment to use the given toolchain and then runs +the specified program. The command may be any program, not just +rustc or cargo. This can be used for testing arbitrary toolchains +without setting an override. + +Commands explicitly proxied by `rustup` (such as `rustc` and `cargo`) +also have a shorthand for this available. The toolchain can be set by +using `+toolchain` as the first argument. These are equivalent: + + cargo +nightly build + + rustup run nightly cargo build"; + +static DOC_HELP: &str = r" +Opens the documentation for the currently active toolchain with the +default browser. + +By default, it opens the documentation index. Use the various flags to +open specific pieces of documentation."; + +criterion_group!(benches, build_rustup, parse_rustup, parse_rustup_with_sc); + +criterion_main!(benches); |