Skip to content

Commit bfeb0be

Browse files
committed
feat(cargo-codspeed): allow build with multiple modes
1 parent 330f8cc commit bfeb0be

4 files changed

Lines changed: 101 additions & 34 deletions

File tree

crates/cargo-codspeed/src/app.rs

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
use crate::{measurement_mode::MeasurementMode, prelude::*, run::run_benches};
1+
use crate::{
2+
measurement_mode::{BuildMode, MeasurementMode},
3+
prelude::*,
4+
run::run_benches,
5+
};
26
use cargo_metadata::MetadataCommand;
3-
use clap::{Args, Parser, Subcommand};
7+
use clap::{ArgAction, Args, Parser, Subcommand};
48
use std::{ffi::OsString, process::exit};
59

610
use crate::build::{build_benches, BuildConfig};
@@ -12,17 +16,12 @@ struct Cli {
1216
#[arg(short, long, global = true)]
1317
quiet: bool,
1418

15-
/// The measurement tool to use for measuring performance.
16-
/// Automatically set to `walltime` on macro runners
17-
#[arg(short, long, global = true, env = "CODSPEED_RUNNER_MODE")]
18-
measurement_mode: Option<MeasurementMode>,
19-
2019
#[command(subcommand)]
2120
command: Commands,
2221
}
2322

2423
const PACKAGE_HELP: &str = "Package Selection";
25-
#[derive(Args)]
24+
#[derive(Args, Clone)]
2625
pub(crate) struct PackageFilters {
2726
/// Select all packages in the workspace
2827
#[arg(long, help_heading = PACKAGE_HELP)]
@@ -35,7 +34,7 @@ pub(crate) struct PackageFilters {
3534
pub(crate) package: Vec<String>,
3635
}
3736

38-
#[derive(Args)]
37+
#[derive(Args, Clone)]
3938
pub(crate) struct BenchTargetFilters {
4039
/// Select only the specified benchmark target (all benchmark targets by default)
4140
#[arg(long, help_heading = TARGET_HELP)]
@@ -89,6 +88,18 @@ enum Commands {
8988

9089
#[command(flatten)]
9190
bench_target_filters: BenchTargetFilters,
91+
92+
/// The measurement tool(s) to use for measuring performance.
93+
/// Can be specified multiple times or comma-separated.
94+
#[arg(
95+
short = 'm',
96+
long = "measurement-mode",
97+
value_delimiter = ',',
98+
action = ArgAction::Append,
99+
help_heading = COMPILATION_HELP,
100+
env = "CODSPEED_RUNNER_MODE"
101+
)]
102+
measurement_mode: Vec<MeasurementMode>,
92103
},
93104
/// Run the previously built benchmarks
94105
Run {
@@ -100,16 +111,18 @@ enum Commands {
100111

101112
#[command(flatten)]
102113
bench_target_filters: BenchTargetFilters,
114+
115+
/// The measurement tool to use for measuring performance.
116+
/// Automatically set to `walltime` on macro runners
117+
#[arg(short = 'm', long = "measurement-mode", env = "CODSPEED_RUNNER_MODE")]
118+
measurement_mode: Option<MeasurementMode>,
103119
},
104120
}
105121

106122
pub fn run(args: impl Iterator<Item = OsString>) -> Result<()> {
107123
let metadata = MetadataCommand::new().exec()?;
108124
let cli = Cli::try_parse_from(args)?;
109125

110-
let measurement_mode = cli.measurement_mode.unwrap_or_default();
111-
eprintln!("[cargo-codspeed] Measurement mode: {measurement_mode:?}\n");
112-
113126
let res = match cli.command {
114127
Commands::Build {
115128
package_filters,
@@ -122,6 +135,7 @@ pub fn run(args: impl Iterator<Item = OsString>) -> Result<()> {
122135
locked,
123136
offline,
124137
frozen,
138+
measurement_mode,
125139
} => {
126140
let passthrough_flags = {
127141
let mut passthrough_flags = Vec::new();
@@ -147,30 +161,51 @@ pub fn run(args: impl Iterator<Item = OsString>) -> Result<()> {
147161
};
148162
let features =
149163
features.map(|f| f.split([' ', ',']).map(|s| s.to_string()).collect_vec());
150-
build_benches(
151-
&metadata,
152-
BuildConfig {
153-
package_filters,
154-
bench_target_filters,
155-
features,
156-
profile,
157-
quiet: cli.quiet,
158-
measurement_mode,
159-
passthrough_flags,
160-
},
161-
)
164+
165+
let build_modes: Vec<BuildMode> = measurement_mode
166+
.into_iter()
167+
.map(BuildMode::from)
168+
.unique()
169+
.collect();
170+
let build_modes = if build_modes.is_empty() {
171+
vec![BuildMode::default()]
172+
} else {
173+
build_modes
174+
};
175+
176+
for build_mode in build_modes {
177+
eprintln!("[cargo-codspeed] Building with build mode: {build_mode}\n");
178+
build_benches(
179+
&metadata,
180+
BuildConfig {
181+
package_filters: package_filters.clone(),
182+
bench_target_filters: bench_target_filters.clone(),
183+
features: features.clone(),
184+
profile: profile.clone(),
185+
quiet: cli.quiet,
186+
build_mode,
187+
passthrough_flags: passthrough_flags.clone(),
188+
},
189+
)?;
190+
}
191+
Ok(())
162192
}
163193
Commands::Run {
164194
benchname,
165195
package_filters,
166196
bench_target_filters,
167-
} => run_benches(
168-
&metadata,
169-
benchname,
170-
package_filters,
171-
bench_target_filters,
172197
measurement_mode,
173-
),
198+
} => {
199+
let mode = measurement_mode.unwrap_or_default();
200+
eprintln!("[cargo-codspeed] Measurement mode: {mode:?}\n");
201+
run_benches(
202+
&metadata,
203+
benchname,
204+
package_filters,
205+
bench_target_filters,
206+
mode,
207+
)
208+
}
174209
};
175210

176211
if let Err(e) = res {

crates/cargo-codspeed/src/build.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
app::{BenchTargetFilters, PackageFilters},
33
helpers::{clear_dir, get_codspeed_target_dir},
4-
measurement_mode::{BuildMode, MeasurementMode},
4+
measurement_mode::BuildMode,
55
prelude::*,
66
};
77
use anyhow::Context;
@@ -23,13 +23,14 @@ struct BuiltBench {
2323
executable_path: Utf8PathBuf,
2424
}
2525

26+
#[derive(Clone)]
2627
pub struct BuildConfig {
2728
pub package_filters: PackageFilters,
2829
pub bench_target_filters: BenchTargetFilters,
2930
pub features: Option<Vec<String>>,
3031
pub profile: String,
3132
pub quiet: bool,
32-
pub measurement_mode: MeasurementMode,
33+
pub build_mode: BuildMode,
3334
pub passthrough_flags: Vec<String>,
3435
}
3536

@@ -301,7 +302,7 @@ impl PackageFilters {
301302
}
302303

303304
pub fn build_benches(metadata: &Metadata, config: BuildConfig) -> Result<()> {
304-
let build_mode = config.measurement_mode.into();
305+
let build_mode = config.build_mode;
305306
let built_benches = BuildOptions {
306307
bench_target_filters: config.bench_target_filters,
307308
package_filters: config.package_filters,

crates/cargo-codspeed/src/measurement_mode.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use clap::ValueEnum;
22
use serde::Serialize;
33
use std::fmt;
44

5-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
66
pub enum BuildMode {
7+
#[default]
78
Analysis,
89
Walltime,
910
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use predicates::str::contains;
2+
3+
mod helpers;
4+
use helpers::*;
5+
6+
const DIR: &str = "tests/simple-criterion.in";
7+
8+
#[test]
9+
fn test_build_multiple_measurement_modes() {
10+
let dir = setup(DIR, Project::Simple);
11+
cargo_codspeed(&dir)
12+
.args(["build", "-m", "simulation", "-m", "walltime"])
13+
.assert()
14+
.success()
15+
.stderr(contains("build mode: analysis"))
16+
.stderr(contains("build mode: walltime"));
17+
teardown(dir);
18+
}
19+
20+
#[test]
21+
fn test_build_multiple_measurement_modes_comma_separated() {
22+
let dir = setup(DIR, Project::Simple);
23+
cargo_codspeed(&dir)
24+
.args(["build", "-m", "simulation,walltime"])
25+
.assert()
26+
.success()
27+
.stderr(contains("build mode: analysis"))
28+
.stderr(contains("build mode: walltime"));
29+
teardown(dir);
30+
}

0 commit comments

Comments
 (0)