Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ rand = "0.8"
shell-words = "1.0"
thiserror = "2.0"
anyhow = "1.0"
clap_complete = "4.2.1"

[target.'cfg(not(windows))'.dependencies]
libc = "0.2"
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fs;

use clap_complete::{generate_to, Shell};
use clap_complete::generate_to;

include!("src/cli.rs");

Expand Down
18 changes: 15 additions & 3 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::ffi::OsString;

use clap::{
builder::NonEmptyStringValueParser, crate_version, Arg, ArgAction, ArgMatches, Command,
ValueHint,
builder::NonEmptyStringValueParser, crate_version, value_parser, Arg, ArgAction, ArgMatches,
Command, ValueHint,
};
use clap_complete::shells::Shell;

pub fn get_cli_arguments<'a, I, T>(args: I) -> ArgMatches
where
Expand All @@ -15,14 +16,25 @@ where
}

/// Build the clap command for parsing command line arguments
fn build_command() -> Command {
pub fn build_command() -> Command {
Command::new("hyperfine")
.version(crate_version!())
.next_line_help(true)
.hide_possible_values(true)
.about("A command-line benchmarking tool.")
.help_expected(true)
.max_term_width(80)
.subcommand_negates_reqs(true)
Comment thread
pollychen-lab marked this conversation as resolved.
.subcommand(
Command::new("generate-shell-completion")
.about("Generate shell completion scripts")
.arg(
Arg::new("shell")
.help("The shell to generate completions for.")
.required(true)
.value_parser(value_parser!(Shell)),
),
)
.arg(
Arg::new("command")
.help("The command to benchmark. This can be the name of an executable, a command \
Expand Down
12 changes: 11 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
use std::env;

use benchmark::scheduler::Scheduler;
use cli::get_cli_arguments;
use cli::{build_command, get_cli_arguments};
use command::Commands;
use export::ExportManager;
use options::Options;

use anyhow::Result;
use clap_complete::{generate, shells::Shell};
use colored::*;

pub mod benchmark;
Expand All @@ -32,6 +33,15 @@ fn run() -> Result<()> {
colored::control::set_virtual_terminal(true).unwrap();

let cli_arguments = get_cli_arguments(env::args_os());
if let Some(("generate-shell-completion", subcommand)) = cli_arguments.subcommand() {
let shell = subcommand
.get_one::<Shell>("shell")
.expect("required by clap");
let mut command = build_command();
generate(*shell, &mut command, "hyperfine", &mut std::io::stdout());
return Ok(());
}

let mut options = Options::from_cli_arguments(&cli_arguments)?;
let commands = Commands::from_cli_arguments(&cli_arguments)?;
let export_manager = ExportManager::from_cli_arguments(
Expand Down
20 changes: 20 additions & 0 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,26 @@ fn runs_successfully() {
.success();
}

#[test]
fn generates_shell_completion() {
hyperfine()
.arg("generate-shell-completion")
.arg("fish")
.assert()
.success()
.stdout(predicate::str::contains("complete").and(predicate::str::contains("hyperfine")));
}

#[test]
fn rejects_unknown_shell_completion() {
hyperfine()
.arg("generate-shell-completion")
.arg("unknown")
.assert()
.failure()
.stderr(predicate::str::contains("invalid value 'unknown'"));
}

#[test]
fn one_run_is_supported() {
hyperfine()
Expand Down