Skip to content

Commit b982cbe

Browse files
feat: add exec-harness binary
This binary is in charge of providing a minimal instrument-hooks wrapper around the command it is given.
1 parent 1e9f1ae commit b982cbe

File tree

4 files changed

+141
-3
lines changed

4 files changed

+141
-3
lines changed

Cargo.lock

Lines changed: 68 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ path = "src/main.rs"
1212

1313
[dependencies]
1414
anyhow = "1.0.75"
15-
clap = { version = "4.4.8", features = ["derive", "env", "color"] }
15+
clap = { workspace = true }
1616
itertools = "0.11.0"
1717
lazy_static = "1.4.0"
1818
log = "0.4.20"
@@ -76,7 +76,10 @@ rstest_reuse = "0.7.0"
7676
shell-quote = "0.7.2"
7777

7878
[workspace]
79-
members = ["crates/runner-shared"]
79+
members = ["crates/exec-harness", "crates/runner-shared"]
80+
81+
[workspace.dependencies]
82+
clap = { version = "4.4.8", features = ["derive", "env", "color"] }
8083

8184
[workspace.metadata.release]
8285
sign-tag = true

crates/exec-harness/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "exec-harness"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
codspeed = "4.1.0"
8+
clap = { workspace = true }

crates/exec-harness/src/main.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use clap::Parser;
2+
use codspeed::instrument_hooks::InstrumentHooks;
3+
4+
#[derive(Parser, Debug)]
5+
#[command(name = "exec-harness")]
6+
#[command(about = "CodSpeed exec harness - wraps commands with performance instrumentation")]
7+
struct Args {
8+
/// Optional benchmark name (defaults to command filename)
9+
#[arg(long)]
10+
name: Option<String>,
11+
12+
/// The command and arguments to execute
13+
command: Vec<String>,
14+
}
15+
16+
fn main() {
17+
let args = Args::parse();
18+
19+
if args.command.is_empty() {
20+
eprintln!("Error: No command provided");
21+
std::process::exit(1);
22+
}
23+
24+
// Derive benchmark name from command if not provided
25+
let bench_name = args.name.unwrap_or_else(|| {
26+
// Extract filename from command path
27+
let cmd = &args.command[0];
28+
std::path::Path::new(cmd)
29+
.file_name()
30+
.and_then(|n| n.to_str())
31+
.map(|s| s.to_string())
32+
.unwrap_or_else(|| "exec_benchmark".to_string())
33+
});
34+
35+
let hooks = InstrumentHooks::instance();
36+
37+
hooks
38+
.set_integration("codspeed-exec", env!("CARGO_PKG_VERSION"))
39+
.unwrap();
40+
hooks.start_benchmark().unwrap();
41+
42+
// Execute the command
43+
let status = std::process::Command::new(&args.command[0])
44+
.args(&args.command[1..])
45+
.status();
46+
47+
hooks.stop_benchmark().unwrap();
48+
hooks.set_executed_benchmark(&bench_name).unwrap();
49+
50+
// Propagate exit code
51+
match status {
52+
Ok(exit_status) => {
53+
std::process::exit(exit_status.code().unwrap_or(1));
54+
}
55+
Err(e) => {
56+
eprintln!("Failed to execute command: {e}");
57+
std::process::exit(1);
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)