Skip to content

Commit d8efbe3

Browse files
committed
feat: add instrumented go shell script
1 parent 9910b71 commit d8efbe3

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

src/run/runner/wall_time/executor.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::run::runner::executor::Executor;
66
use crate::run::runner::helpers::env::{get_base_injected_env, is_codspeed_debug_enabled};
77
use crate::run::runner::helpers::get_bench_command::get_bench_command;
88
use crate::run::runner::helpers::run_command_with_log_pipe::run_command_with_log_pipe;
9+
use crate::run::runner::wall_time::introspected_golang::setup_introspected_go;
910
use crate::run::runner::{ExecutorName, RunData};
1011
use crate::run::{check_system::SystemInfo, config::Config};
1112
use async_trait::async_trait;
@@ -106,7 +107,19 @@ impl WallTimeExecutor {
106107
.map(|(k, v)| format!("export {k}={v}",))
107108
.collect::<Vec<_>>()
108109
.join("\n");
109-
let combined_env = format!("{system_env}\n{base_injected_env}");
110+
111+
// We need to intercept the `go` command to ensure we can run it with our custom runner.
112+
let path_env = std::env::var("PATH").unwrap_or_default();
113+
let path_env = format!(
114+
"export PATH={}:{}",
115+
setup_introspected_go()
116+
.map_err(|e| anyhow!("failed to setup Go introspection. {}", e))?
117+
.to_str()
118+
.unwrap(),
119+
path_env
120+
);
121+
122+
let combined_env = format!("{system_env}\n{base_injected_env}\n{path_env}");
110123

111124
let mut env_file = NamedTempFile::new()?;
112125
env_file.write_all(combined_env.as_bytes())?;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
debug_log() {
6+
if [ "${CODSPEED_LOG:-}" = "debug" ]; then
7+
echo "[DEBUG go.sh] $*" >&2
8+
fi
9+
}
10+
11+
debug_log "Called with arguments: $*"
12+
debug_log "Number of arguments: $#"
13+
14+
# Find the real go binary, so that we don't end up in infinite recursion
15+
REAL_GO=$(which -a go | grep -v "$(realpath "$0")" | head -1)
16+
if [ -z "$REAL_GO" ]; then
17+
echo "ERROR: Could not find real go binary" >&2
18+
exit 1
19+
fi
20+
21+
# Check if we have any arguments
22+
if [ $# -eq 0 ]; then
23+
debug_log "No arguments provided, using standard go binary"
24+
"$REAL_GO"
25+
exit $?
26+
fi
27+
28+
# Check if first argument is "test"
29+
if [ "$1" = "test" ]; then
30+
debug_log "Detected 'test' command, routing to go-runner"
31+
32+
# Find go-runner or install if not found
33+
GO_RUNNER=$(which go-runner 2>/dev/null || true)
34+
if [ -z "$GO_RUNNER" ]; then
35+
echo "ERROR: go-runner not found, attempting to install..." >&2
36+
curl -fsSL http://github.com/CodSpeedHQ/runner/releases/latest/download/go-runner-installer.sh | bash -s -- --quiet
37+
GO_RUNNER=$(which go-runner 2>/dev/null || true)
38+
fi
39+
40+
debug_log "Using go-runner at: $GO_RUNNER"
41+
debug_log "Full command: RUST_LOG=info $GO_RUNNER $*"
42+
43+
"$GO_RUNNER" "$@"
44+
else
45+
debug_log "Detected non-test command ('$1'), routing to standard go binary"
46+
debug_log "Full command: $REAL_GO $*"
47+
"$REAL_GO" "$@"
48+
fi
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use crate::prelude::*;
2+
use std::{env, fs::File, io::Write, os::unix::fs::PermissionsExt, path::PathBuf};
3+
4+
const INTROSPECTED_GO_SCRIPT: &str = include_str!("go.sh");
5+
6+
/// Creates the `go` script that will replace the `go` binary while running
7+
/// Returns the path to the script folder, which should be added to the PATH environment variable
8+
pub fn setup_introspected_go() -> Result<PathBuf> {
9+
let script_folder = env::temp_dir().join("codspeed_introspected_go");
10+
std::fs::create_dir_all(&script_folder)?;
11+
let script_path = script_folder.join("go");
12+
let mut script_file = File::create(script_path)?;
13+
script_file.write_all(INTROSPECTED_GO_SCRIPT.as_bytes())?;
14+
// Make the script executable
15+
let mut perms = script_file.metadata()?.permissions();
16+
perms.set_mode(0o755);
17+
script_file.set_permissions(perms)?;
18+
Ok(script_folder)
19+
}

src/run/runner/wall_time/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod executor;
2+
pub mod introspected_golang;
23
pub mod perf;

0 commit comments

Comments
 (0)