2018-03-24 18:30:52 -04:00
|
|
|
use atty;
|
|
|
|
|
use atty::Stream;
|
2019-05-07 11:55:38 +02:00
|
|
|
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
|
2018-05-22 22:57:51 +02:00
|
|
|
use std::ffi::OsString;
|
2018-03-24 18:30:52 -04:00
|
|
|
|
|
|
|
|
pub fn get_arg_matches<T>(args: T) -> ArgMatches<'static>
|
|
|
|
|
where
|
|
|
|
|
T: Iterator<Item = OsString>,
|
|
|
|
|
{
|
|
|
|
|
let app = build_app();
|
|
|
|
|
app.get_matches_from(args)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Build the clap app for parsing command line arguments
|
|
|
|
|
fn build_app() -> App<'static, 'static> {
|
|
|
|
|
let clap_color_setting = if atty::is(Stream::Stdout) {
|
|
|
|
|
AppSettings::ColoredHelp
|
|
|
|
|
} else {
|
|
|
|
|
AppSettings::ColorNever
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
App::new("hyperfine")
|
|
|
|
|
.version(crate_version!())
|
|
|
|
|
.setting(clap_color_setting)
|
|
|
|
|
.setting(AppSettings::DeriveDisplayOrder)
|
|
|
|
|
.setting(AppSettings::UnifiedHelpMessage)
|
|
|
|
|
.setting(AppSettings::NextLineHelp)
|
|
|
|
|
.setting(AppSettings::HidePossibleValuesInHelp)
|
|
|
|
|
.max_term_width(90)
|
|
|
|
|
.about("A command-line benchmarking tool.")
|
|
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("command")
|
|
|
|
|
.help("Command to benchmark")
|
|
|
|
|
.required(true)
|
|
|
|
|
.multiple(true)
|
|
|
|
|
.empty_values(false),
|
|
|
|
|
)
|
|
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("warmup")
|
|
|
|
|
.long("warmup")
|
|
|
|
|
.short("w")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("NUM")
|
|
|
|
|
.help(
|
|
|
|
|
"Perform NUM warmup runs before the actual benchmark. This can be used \
|
|
|
|
|
to fill (disk) caches for I/O-heavy programs.",
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("min-runs")
|
|
|
|
|
.long("min-runs")
|
|
|
|
|
.short("m")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("NUM")
|
|
|
|
|
.help("Perform at least NUM runs for each command (default: 10)."),
|
|
|
|
|
)
|
2018-09-09 14:10:36 +01:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("max-runs")
|
|
|
|
|
.long("max-runs")
|
|
|
|
|
.short("M")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("NUM")
|
|
|
|
|
.help("Perform at most NUM runs for each command."),
|
|
|
|
|
)
|
|
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("runs")
|
|
|
|
|
.long("runs")
|
2018-09-09 21:52:58 +01:00
|
|
|
.conflicts_with_all(&["max-runs", "min-runs"])
|
2018-09-09 14:10:36 +01:00
|
|
|
.short("r")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("NUM")
|
|
|
|
|
.help("Perform exactly NUM runs for each command."),
|
|
|
|
|
)
|
2018-03-24 18:30:52 -04:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("prepare")
|
|
|
|
|
.long("prepare")
|
|
|
|
|
.short("p")
|
|
|
|
|
.takes_value(true)
|
2019-10-02 18:56:55 +05:45
|
|
|
.multiple(true)
|
|
|
|
|
.number_of_values(1)
|
2018-03-24 18:30:52 -04:00
|
|
|
.value_name("CMD")
|
|
|
|
|
.help(
|
2019-10-13 18:10:53 +05:45
|
|
|
"Execute CMD before each timing run. This is useful for \
|
|
|
|
|
clearing disk caches, for example. \nThe --prepare option can \
|
|
|
|
|
be specified once for all commands or multiple times, once for \
|
|
|
|
|
each command. In the latter case, each preparation command will \
|
|
|
|
|
be run prior to the corresponding benchmark command.",
|
2018-03-24 18:30:52 -04:00
|
|
|
),
|
|
|
|
|
)
|
2019-01-07 23:12:30 -08:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("cleanup")
|
|
|
|
|
.long("cleanup")
|
|
|
|
|
.short("c")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("CMD")
|
|
|
|
|
.help(
|
2019-01-14 08:33:38 -08:00
|
|
|
"Execute CMD after the completion of all benchmarking \
|
|
|
|
|
runs for each individual command to be benchmarked. \
|
|
|
|
|
This is useful if the commands to be benchmarked produce \
|
|
|
|
|
artifacts that need to be cleaned up."
|
2019-01-07 23:12:30 -08:00
|
|
|
),
|
|
|
|
|
)
|
2018-03-24 18:30:52 -04:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("parameter-scan")
|
|
|
|
|
.long("parameter-scan")
|
|
|
|
|
.short("P")
|
2018-10-29 18:44:44 -07:00
|
|
|
.takes_value(true)
|
|
|
|
|
.allow_hyphen_values(true)
|
|
|
|
|
.value_names(&["VAR", "MIN", "MAX"])
|
2018-03-24 18:30:52 -04:00
|
|
|
.help(
|
|
|
|
|
"Perform benchmark runs for each value in the range MIN..MAX. Replaces the \
|
|
|
|
|
string '{VAR}' in each command by the current parameter value.",
|
2018-10-29 18:44:44 -07:00
|
|
|
),
|
2018-03-24 18:30:52 -04:00
|
|
|
)
|
2019-08-22 00:50:20 +05:30
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("parameter-step-size")
|
|
|
|
|
.long("parameter-step-size")
|
2019-09-01 16:04:21 +05:30
|
|
|
.short("D")
|
2019-08-22 00:50:20 +05:30
|
|
|
.takes_value(true)
|
2019-09-01 16:04:21 +05:30
|
|
|
.value_names(&["DELTA"])
|
2019-08-22 00:50:20 +05:30
|
|
|
.requires("parameter-scan")
|
|
|
|
|
.help(
|
2019-09-13 00:54:50 +01:00
|
|
|
"This argument requires --parameter-scan to be specified as well. \
|
2019-09-01 16:04:21 +05:30
|
|
|
Traverse the range MIN..MAX in steps of DELTA.",
|
2019-08-22 00:50:20 +05:30
|
|
|
),
|
|
|
|
|
)
|
2018-03-24 18:30:52 -04:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("style")
|
|
|
|
|
.long("style")
|
|
|
|
|
.short("s")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("TYPE")
|
2018-09-15 10:11:35 -07:00
|
|
|
.possible_values(&["auto", "basic", "full", "nocolor", "color"])
|
2018-03-24 18:30:52 -04:00
|
|
|
.help(
|
|
|
|
|
"Set output style type (default: auto). Set this to 'basic' to disable output \
|
|
|
|
|
coloring and interactive elements. Set it to 'full' to enable all effects \
|
|
|
|
|
even if no interactive terminal was detected. Set this to 'nocolor' to \
|
2019-01-02 17:13:05 +01:00
|
|
|
keep the interactive output without any colors. Set this to 'color' to keep \
|
2018-09-15 10:11:35 -07:00
|
|
|
the colors without any interactive output.",
|
2018-03-24 18:30:52 -04:00
|
|
|
),
|
|
|
|
|
)
|
2018-10-30 19:30:17 -07:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("shell")
|
|
|
|
|
.long("shell")
|
|
|
|
|
.short("S")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("SHELL")
|
|
|
|
|
.overrides_with("shell")
|
|
|
|
|
.help("Set the shell to use (default: sh) for executing benchmarked commands."),
|
|
|
|
|
)
|
2018-03-24 18:30:52 -04:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("ignore-failure")
|
|
|
|
|
.long("ignore-failure")
|
|
|
|
|
.short("i")
|
|
|
|
|
.help("Ignore non-zero exit codes."),
|
|
|
|
|
)
|
2018-10-29 18:44:44 -07:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("time-unit")
|
|
|
|
|
.long("time-unit")
|
|
|
|
|
.short("u")
|
|
|
|
|
.takes_value(true)
|
2018-11-01 20:52:25 -07:00
|
|
|
.value_name("UNIT")
|
2018-10-29 18:44:44 -07:00
|
|
|
.possible_values(&["millisecond", "second"])
|
2018-11-01 20:52:25 -07:00
|
|
|
.help("Set the time unit used. Possible values: millisecond, second."),
|
2018-10-29 18:44:44 -07:00
|
|
|
)
|
2019-01-29 18:02:19 -05:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("export-asciidoc")
|
|
|
|
|
.long("export-asciidoc")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("FILE")
|
|
|
|
|
.help("Export the timing summary statistics as an Asciidoc table to the given FILE."),
|
|
|
|
|
)
|
2018-03-24 18:30:52 -04:00
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("export-csv")
|
|
|
|
|
.long("export-csv")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("FILE")
|
2018-12-05 10:15:09 +01:00
|
|
|
.help("Export the timing summary statistics as CSV to the given FILE."),
|
2018-03-24 18:30:52 -04:00
|
|
|
)
|
|
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("export-json")
|
|
|
|
|
.long("export-json")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("FILE")
|
2018-12-05 10:15:09 +01:00
|
|
|
.help("Export the timing summary statistics and timings of individual runs as JSON to the given FILE."),
|
2018-03-24 18:30:52 -04:00
|
|
|
)
|
|
|
|
|
.arg(
|
|
|
|
|
Arg::with_name("export-markdown")
|
|
|
|
|
.long("export-markdown")
|
|
|
|
|
.takes_value(true)
|
|
|
|
|
.value_name("FILE")
|
2018-12-05 10:15:09 +01:00
|
|
|
.help("Export the timing summary statistics as a Markdown table to the given FILE."),
|
2018-03-24 18:30:52 -04:00
|
|
|
)
|
2018-05-21 18:14:53 +02:00
|
|
|
.arg(
|
2018-05-21 21:04:30 +02:00
|
|
|
Arg::with_name("show-output")
|
|
|
|
|
.long("show-output")
|
2018-05-21 18:14:53 +02:00
|
|
|
.conflicts_with("style")
|
2018-05-22 22:57:51 +02:00
|
|
|
.help(
|
|
|
|
|
"Print the stdout and stderr of the benchmark instead of suppressing it. \
|
|
|
|
|
This will increase the time it takes for benchmarks to run, \
|
|
|
|
|
so it should only be used for debugging purposes or \
|
|
|
|
|
when trying to benchmark output speed.",
|
|
|
|
|
),
|
2018-05-21 18:14:53 +02:00
|
|
|
)
|
2018-03-24 18:30:52 -04:00
|
|
|
.help_message("Print this help message.")
|
|
|
|
|
.version_message("Show version information.")
|
|
|
|
|
}
|