Skip to content

Commit 29ab360

Browse files
committed
feat: support --features build flag
1 parent 814a94b commit 29ab360

File tree

7 files changed

+115
-7
lines changed

7 files changed

+115
-7
lines changed

crates/cargo-codspeed/src/app.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ enum Commands {
2525
/// Package to build benchmarks for (if using a workspace)
2626
#[arg(short, long)]
2727
package: Option<String>,
28+
/// Space or comma separated list of features to activate
29+
#[arg(short = 'F', long)]
30+
features: Option<String>,
2831
},
2932
/// Run the previously built benchmarks
3033
Run {
@@ -50,7 +53,18 @@ pub fn run(args: impl Iterator<Item = OsString>) -> Result<()> {
5053
let workspace = Workspace::new(&manifest_path, &cargo_config)?;
5154

5255
let res = match cli.command {
53-
Commands::Build { benches, package } => build_benches(&workspace, benches, package),
56+
Commands::Build {
57+
benches,
58+
package,
59+
features,
60+
} => {
61+
let features = features.map(|f| {
62+
f.split(|c| c == ' ' || c == ',')
63+
.map(|s| s.to_string())
64+
.collect_vec()
65+
});
66+
build_benches(&workspace, benches, package, features)
67+
}
5468
Commands::Run { benches, package } => run_benches(&workspace, benches, package),
5569
};
5670

crates/cargo-codspeed/src/build.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,32 @@ use crate::{
33
prelude::*,
44
};
55

6-
use std::fs::create_dir_all;
6+
use std::{collections::BTreeSet, fs::create_dir_all, rc::Rc};
77

88
use cargo::{
9-
core::{Package, Workspace},
9+
core::{FeatureValue, Package, Workspace},
1010
ops::{CompileFilter, CompileOptions, Packages},
11-
util::command_prelude::CompileMode,
11+
util::{command_prelude::CompileMode, interning::InternedString},
1212
Config,
1313
};
1414
use termcolor::Color;
1515

16-
fn get_compile_options(config: &Config, package: &Package, bench: &str) -> Result<CompileOptions> {
16+
fn get_compile_options(
17+
config: &Config,
18+
features: &Option<Vec<String>>,
19+
package: &Package,
20+
bench: &str,
21+
) -> Result<CompileOptions> {
1722
let mut compile_opts = CompileOptions::new(config, CompileMode::Build)?;
1823
compile_opts.spec = Packages::Packages(vec![package.name().to_string()]);
24+
if let Some(features) = features {
25+
compile_opts.cli_features.features = Rc::new(
26+
features
27+
.iter()
28+
.map(|s| FeatureValue::Feature(InternedString::new(s.as_str())))
29+
.collect::<BTreeSet<FeatureValue>>(),
30+
);
31+
}
1932
compile_opts.build_config.requested_profile = "release".into();
2033
compile_opts.filter = CompileFilter::from_raw_arguments(
2134
false,
@@ -36,6 +49,7 @@ pub fn build_benches(
3649
ws: &Workspace,
3750
selected_benches: Option<Vec<String>>,
3851
package_name: Option<String>,
52+
features: Option<Vec<String>>,
3953
) -> Result<()> {
4054
let package = match package_name.as_ref() {
4155
Some(package_name) => ws
@@ -82,7 +96,7 @@ pub fn build_benches(
8296
ws.config()
8397
.shell()
8498
.status_with_color("Building", bench.name(), Color::Yellow)?;
85-
let compile_opts = get_compile_options(config, package, bench.name())?;
99+
let compile_opts = get_compile_options(config, &features, package, bench.name())?;
86100
let result = cargo::ops::compile(ws, &compile_opts)?;
87101
let built_targets = result
88102
.tests
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cargo.lock
2+
target/
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[package]
2+
name = "features"
3+
version = "0.0.0"
4+
edition = "2021"
5+
publish = false
6+
7+
[dependencies]
8+
bencher = "0.1.5"
9+
codspeed = { path = "../../../codspeed" }
10+
codspeed-bencher-compat = { path = "../../../bencher_compat" }
11+
12+
[features]
13+
sample_feature = []
14+
15+
[workspace]
16+
17+
18+
[[bench]]
19+
name = "bench"
20+
harness = false
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use codspeed::codspeed::black_box;
2+
use codspeed_bencher_compat::{benchmark_group, benchmark_main, Bencher};
3+
4+
#[cfg(not(feature = "sample_feature"))]
5+
pub fn without_feature(bench: &mut Bencher) {
6+
bench.iter(|| (0..100).fold(0, |x, y| black_box(x + y)))
7+
}
8+
#[cfg(not(feature = "sample_feature"))]
9+
benchmark_group!(benches, without_feature);
10+
11+
#[cfg(feature = "sample_feature")]
12+
pub fn with_feature(bench: &mut Bencher) {
13+
bench.iter(|| (0..100).fold(0, |x, y| black_box(x + y)))
14+
}
15+
#[cfg(feature = "sample_feature")]
16+
benchmark_group!(benches, with_feature);
17+
18+
benchmark_main!(benches);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use predicates::{prelude::PredicateBooleanExt, str::contains};
2+
3+
mod helpers;
4+
use helpers::*;
5+
6+
const DIR: &str = "tests/features.in";
7+
8+
#[test]
9+
fn test_without_feature() {
10+
let dir = setup(DIR, Project::Features);
11+
cargo_codspeed(&dir).arg("build").assert().success();
12+
cargo_codspeed(&dir)
13+
.arg("run")
14+
.assert()
15+
.success()
16+
.stderr(contains("Finished running 1 benchmark suite(s)"))
17+
.stdout(contains("without_feature"))
18+
.stdout(contains("with_feature").not());
19+
teardown(dir);
20+
}
21+
22+
#[test]
23+
fn test_with_feature() {
24+
let dir = setup(DIR, Project::Features);
25+
cargo_codspeed(&dir)
26+
.arg("build")
27+
.arg("-F")
28+
.arg("sample_feature")
29+
.assert()
30+
.success();
31+
cargo_codspeed(&dir)
32+
.arg("run")
33+
.assert()
34+
.success()
35+
.stderr(contains("Finished running 1 benchmark suite(s)"))
36+
.stdout(contains("with_feature"))
37+
.stdout(contains("without_feature").not());
38+
teardown(dir);
39+
}

crates/cargo-codspeed/tests/helpers.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ fn replace_in_file(path: &str, from: &str, to: &str) {
1818
#[allow(dead_code)]
1919
pub enum Project {
2020
Simple,
21+
Features,
2122
Workspace,
2223
}
2324

@@ -35,7 +36,7 @@ pub fn setup(dir: &str, project: Project) -> String {
3536
let package_root = PathBuf::from_str(env!("CARGO_MANIFEST_DIR")).unwrap();
3637
let workspace_root = package_root.parent().unwrap().parent().unwrap();
3738
match project {
38-
Project::Simple => {
39+
Project::Simple | Project::Features => {
3940
replace_in_file(
4041
tmp_dir.join("Cargo.toml").to_str().unwrap(),
4142
"../../..",

0 commit comments

Comments
 (0)