Skip to content

Commit d32d356

Browse files
committed
refactor(cli): centralize internal re-exec via InternalCommands::get_command_builder
Each InternalCommands variant now owns how it's re-invoked: the current_exe() resolution, CommandBuilder construction, and argv layout all live in one place. The samply call site collapses from hand-rolled CommandBuilder setup to a single chained expression.
1 parent 9cf182e commit d32d356

4 files changed

Lines changed: 38 additions & 19 deletions

File tree

src/cli/mod.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod auth;
22
pub(crate) mod exec;
33
pub(crate) mod experimental;
44
pub(crate) mod run;
5-
mod samply;
5+
pub(crate) mod samply;
66
mod setup;
77
mod shared;
88
mod show;
@@ -17,6 +17,7 @@ use std::path::PathBuf;
1717
use crate::{
1818
api_client::CodSpeedAPIClient,
1919
config::CodSpeedConfig,
20+
executor::helpers::command::CommandBuilder,
2021
local_logger::{CODSPEED_U8_COLOR_CODE, IS_TTY, init_local_logger},
2122
prelude::*,
2223
project_config::DiscoveredProjectConfig,
@@ -125,12 +126,29 @@ enum Commands {
125126

126127
/// Subcommands the CLI uses to re-invoke itself; not user-facing entry points.
127128
#[derive(Subcommand, Debug)]
128-
enum InternalCommands {
129+
pub(crate) enum InternalCommands {
129130
/// Run the bundled samply profiler. Args are forwarded to samply.
130131
#[command(disable_help_flag = true, disable_help_subcommand = true)]
131132
Samply(samply::SamplyArgs),
132133
}
133134

135+
impl InternalCommands {
136+
/// Build a [`CommandBuilder`] that re-execs the current binary into this
137+
/// internal subcommand. Each variant owns its own arg layout.
138+
pub fn get_command_builder(&self) -> Result<CommandBuilder> {
139+
let current_exe = std::env::current_exe()
140+
.context("failed to resolve current executable for internal subcommand")?;
141+
let mut builder = CommandBuilder::new(current_exe);
142+
match self {
143+
InternalCommands::Samply(args) => {
144+
builder.arg("samply");
145+
builder.args(args.args.iter().cloned());
146+
}
147+
}
148+
Ok(builder)
149+
}
150+
}
151+
134152
pub async fn run() -> Result<()> {
135153
let cli = Cli::parse();
136154
// Important: keep this after the Cli::parse() because the function can exit the process by itself, skipping the drop of the CursorGuard

src/cli/samply.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::prelude::*;
77
#[derive(Debug, clap::Args)]
88
pub struct SamplyArgs {
99
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
10-
args: Vec<std::ffi::OsString>,
10+
pub args: Vec<std::ffi::OsString>,
1111
}
1212

1313
pub fn run(args: SamplyArgs) -> Result<()> {

src/executor/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::fmt::Display;
22

33
pub mod config;
44
mod execution_context;
5-
mod helpers;
5+
pub(crate) mod helpers;
66
mod interfaces;
77
mod memory;
88
pub mod orchestrator;

src/executor/wall_time/profiler/samply/mod.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Samply profiler integration.
22
3+
use crate::cli::InternalCommands;
4+
use crate::cli::samply::SamplyArgs;
35
use crate::executor::ExecutorConfig;
46
use crate::executor::helpers::command::CommandBuilder;
57
use crate::executor::shared::fifo::FifoBenchmarkData;
@@ -53,21 +55,20 @@ impl Profiler for SamplyProfiler {
5355

5456
// samply is bundled into this binary as the `samply` subcommand;
5557
// re-exec ourselves so we don't depend on a system install.
56-
let current_exe = std::env::current_exe()
57-
.context("failed to resolve current executable for bundled samply")?;
58-
let mut samply_builder = CommandBuilder::new(current_exe);
59-
samply_builder.args([
60-
"samply",
61-
"record",
62-
"--presymbolicate",
63-
"--no-open",
64-
"--save-only",
65-
"--rate",
66-
&SAMPLING_RATE_HZ.to_string(),
67-
]);
68-
samply_builder.arg("-o");
69-
samply_builder.arg(&output_path);
70-
samply_builder.arg("--");
58+
let samply_builder = InternalCommands::Samply(SamplyArgs {
59+
args: vec![
60+
"record".into(),
61+
"--presymbolicate".into(),
62+
"--no-open".into(),
63+
"--save-only".into(),
64+
"--rate".into(),
65+
SAMPLING_RATE_HZ.to_string().into(),
66+
"-o".into(),
67+
output_path.clone().into(),
68+
"--".into(),
69+
],
70+
})
71+
.get_command_builder()?;
7172

7273
cmd_builder.wrap_with(samply_builder);
7374
self.output_path = Some(output_path);

0 commit comments

Comments
 (0)