Skip to content

Commit e820139

Browse files
committed
feat: go test cli compat
1 parent bf3ff41 commit e820139

File tree

3 files changed

+157
-36
lines changed

3 files changed

+157
-36
lines changed

go-runner/src/cli.rs

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#[derive(Debug)]
2+
pub enum CliExit {
3+
Help,
4+
Version,
5+
MissingArgument,
6+
UnknownFlag,
7+
}
8+
9+
#[derive(Debug)]
10+
pub struct Cli {
11+
/// Run only benchmarks matching regexp
12+
pub bench: String,
13+
}
14+
15+
impl Cli {
16+
pub fn parse() -> Self {
17+
match Self::parse_args(std::env::args().skip(1)) {
18+
Ok(cli) => cli,
19+
Err(CliExit::Help) => std::process::exit(0),
20+
Err(CliExit::Version) => std::process::exit(0),
21+
Err(CliExit::MissingArgument) => std::process::exit(2),
22+
Err(CliExit::UnknownFlag) => std::process::exit(1),
23+
}
24+
}
25+
26+
fn parse_args(mut args: impl Iterator<Item = String>) -> Result<Self, CliExit> {
27+
let mut bench = ".".to_string();
28+
29+
// We currently only support the `test` subcommand.
30+
let cmd = args.next();
31+
assert!(
32+
cmd == Some("test".to_string()),
33+
"Expected 'test' as the first argument, got {cmd:?}",
34+
);
35+
36+
while let Some(arg) = args.next() {
37+
match arg.as_str() {
38+
"-h" | "--help" => {
39+
println!(
40+
"\
41+
The Codspeed Go Benchmark Runner
42+
43+
USAGE:
44+
go-runner test [OPTIONS]
45+
46+
OPTIONS:
47+
-bench <pattern> Run only benchmarks matching regexp (defaults to '.')
48+
-h, --help Print help information
49+
-V, --version Print version information"
50+
);
51+
return Err(CliExit::Help);
52+
}
53+
"-V" | "--version" => {
54+
println!("{}", env!("CARGO_PKG_VERSION"));
55+
return Err(CliExit::Version);
56+
}
57+
"-bench" => {
58+
bench = args.next().ok_or_else(|| {
59+
eprintln!("error: `-bench` requires a pattern");
60+
CliExit::MissingArgument
61+
})?;
62+
}
63+
s if s.starts_with("-bench=") => {
64+
bench = s.split_once('=').unwrap().1.to_string();
65+
}
66+
67+
s if s.starts_with('-') => {
68+
eprintln!("Unknown flag: {s}");
69+
return Err(CliExit::UnknownFlag);
70+
}
71+
72+
_ => {
73+
eprintln!(
74+
"warning: package arguments are not currently supported, ignoring '{arg}'"
75+
);
76+
// Consume and ignore all remaining arguments
77+
for remaining_arg in args {
78+
eprintln!(
79+
"warning: package arguments are not currently supported, ignoring '{remaining_arg}'"
80+
);
81+
}
82+
break;
83+
}
84+
}
85+
}
86+
Ok(Self { bench })
87+
}
88+
}
89+
90+
#[cfg(test)]
91+
mod tests {
92+
use super::*;
93+
94+
fn str_to_iter(cmd: &str) -> Result<Cli, CliExit> {
95+
let args: Vec<String> = if cmd.trim().is_empty() {
96+
Vec::new()
97+
} else {
98+
cmd.split_whitespace()
99+
.map(|s| s.to_string())
100+
.skip(1)
101+
.collect()
102+
};
103+
Cli::parse_args(args.into_iter())
104+
}
105+
106+
#[test]
107+
fn test_cli_parse_defaults() {
108+
let cli = str_to_iter("go-runner test").unwrap();
109+
assert_eq!(cli.bench, ".");
110+
}
111+
112+
#[test]
113+
fn test_cli_parse_with_bench_flag() {
114+
let cli = str_to_iter("go-runner test -bench Test").unwrap();
115+
assert_eq!(cli.bench, "Test");
116+
117+
let cli = str_to_iter("go-runner test -bench=BenchmarkFoo").unwrap();
118+
assert_eq!(cli.bench, "BenchmarkFoo");
119+
}
120+
121+
#[test]
122+
fn test_cli_parse_ignores_packages() {
123+
let cli = str_to_iter("go-runner test package1 package2").unwrap();
124+
assert_eq!(cli.bench, ".");
125+
}
126+
127+
#[test]
128+
fn test_cli_parse_help_flag() {
129+
let result = str_to_iter("go-runner test -h");
130+
assert!(matches!(result, Err(CliExit::Help)));
131+
132+
let result = str_to_iter("go-runner test --help");
133+
assert!(matches!(result, Err(CliExit::Help)));
134+
}
135+
136+
#[test]
137+
fn test_cli_parse_version_flag() {
138+
let result = str_to_iter("go-runner test -V");
139+
assert!(matches!(result, Err(CliExit::Version)));
140+
141+
let result = str_to_iter("go-runner test --version");
142+
assert!(matches!(result, Err(CliExit::Version)));
143+
}
144+
145+
#[test]
146+
fn test_cli_parse_invalid() {
147+
let result = str_to_iter("go-runner test -bench");
148+
assert!(matches!(result, Err(CliExit::MissingArgument)));
149+
150+
let result = str_to_iter("go-runner test -unknown");
151+
assert!(matches!(result, Err(CliExit::UnknownFlag)));
152+
}
153+
}

go-runner/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{
55
};
66

77
mod builder;
8+
pub mod cli;
89
pub mod prelude;
910
mod results;
1011
pub(crate) mod utils;

go-runner/src/main.rs

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,11 @@
1-
use clap::{Parser, Subcommand};
2-
use std::path::PathBuf;
3-
4-
#[derive(Parser)]
5-
#[command(version, about = "A Go benchmark runner for CodSpeed", long_about = None)]
6-
struct Cli {
7-
#[command(subcommand)]
8-
command: Commands,
9-
}
10-
11-
#[derive(Subcommand)]
12-
enum Commands {
13-
/// Build and run benchmarks with CodSpeed instrumentation
14-
Run {
15-
/// The project directory path (defaults to current directory)
16-
#[arg(default_value = ".")]
17-
path: PathBuf,
18-
/// Equivalent to the `-bench regexp` flag in `go test`.
19-
///
20-
/// Run only those benchmarks matching a regular expression.
21-
/// By default, no benchmarks are run.
22-
/// To run all benchmarks, use '-bench .' or '-bench=.'.
23-
/// The regular expression is split by unbracketed slash (/)
24-
/// characters into a sequence of regular expressions, and each
25-
/// part of a benchmark's identifier must match the corresponding
26-
/// element in the sequence, if any.
27-
#[arg(long, default_value = ".")]
28-
bench: String,
29-
},
30-
}
1+
use go_runner::cli::Cli;
2+
use std::path::Path;
313

324
fn main() -> anyhow::Result<()> {
335
env_logger::init();
346

357
let cli = Cli::parse();
36-
37-
match &cli.command {
38-
Commands::Run { path, bench } => {
39-
go_runner::run_benchmarks(path, bench)?;
40-
}
41-
}
8+
go_runner::run_benchmarks(Path::new("."), &cli.bench)?;
429

4310
Ok(())
4411
}

0 commit comments

Comments
 (0)