Skip to content

Commit 05f191e

Browse files
committed
--wip-- [skip ci]
1 parent be64f4f commit 05f191e

File tree

11 files changed

+154
-39
lines changed

11 files changed

+154
-39
lines changed

crates/cargo-codspeed/src/build.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
helpers::{clear_dir, get_codspeed_dir},
2+
helpers::{clear_dir, get_codspeed_target_dir},
33
prelude::*,
44
};
55

@@ -61,7 +61,6 @@ pub fn build_benches(
6161
Some(package_name) => ws.members()
6262
.find(|p| p.name().to_string() == *package_name)
6363
.ok_or_else(|| anyhow!("Package {} not found", package_name))?
64-
6564
,
6665
None => ws.current().map_err(|_| anyhow!("No package found. If working with a workspace please use the -p option to specify a member."))?
6766
};
@@ -82,7 +81,7 @@ pub fn build_benches(
8281
all_benches
8382
};
8483

85-
ws.config().shell().set_verbosity(Verbosity::Normal);
84+
ws.config().shell().set_verbosity(Verbosity::Verbose);
8685
ws.config().shell().status_with_color(
8786
"Collected",
8887
format!(
@@ -125,7 +124,7 @@ pub fn build_benches(
125124
.shell()
126125
.status_with_color("Built", benches_names_str, Color::Green)?;
127126

128-
let mut codspeed_target_dir = get_codspeed_dir(ws);
127+
let mut codspeed_target_dir = get_codspeed_target_dir(ws);
129128
create_dir_all(&codspeed_target_dir)?;
130129
if let Some(name) = package_name.as_ref() {
131130
codspeed_target_dir = codspeed_target_dir.join(name);

crates/cargo-codspeed/src/helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::prelude::*;
22
use std::path::{Path, PathBuf};
33

4-
pub fn get_codspeed_dir(ws: &Workspace) -> PathBuf {
4+
pub fn get_codspeed_target_dir(ws: &Workspace) -> PathBuf {
55
ws.target_dir()
66
.as_path_unlocked()
77
.to_path_buf()

crates/cargo-codspeed/src/run.rs

Lines changed: 69 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,116 @@
1+
use std::path::PathBuf;
2+
13
use anyhow::anyhow;
4+
use cargo::core::Package;
25
use termcolor::Color;
36

47
use crate::{
5-
helpers::{get_codspeed_dir, read_dir_recursive},
8+
helpers::{get_codspeed_target_dir, read_dir_recursive},
69
prelude::*,
710
};
811

12+
struct BenchToRun {
13+
bench_path: PathBuf,
14+
bench_name: String,
15+
package_name: String,
16+
working_directory: PathBuf,
17+
}
18+
919
pub fn run_benches(
1020
ws: &Workspace,
11-
benches: Option<Vec<String>>,
21+
selected_bench_names: Option<Vec<String>>,
1222
package: Option<String>,
1323
) -> Result<()> {
14-
let mut codspeed_dir = get_codspeed_dir(ws);
24+
let codspeed_target_dir = get_codspeed_target_dir(ws);
1525

16-
if let Some(package) = package {
17-
codspeed_dir.push(package.clone());
18-
if !codspeed_dir.exists() {
19-
return Err(anyhow!(
26+
let packages_to_run = if let Some(package) = package.as_ref() {
27+
let p = ws
28+
.members()
29+
.find(|m| m.manifest().name().to_string().as_str() == package);
30+
if let Some(p) = p {
31+
vec![p]
32+
} else {
33+
bail!("Package {} not found", package);
34+
}
35+
} else {
36+
ws.default_members().collect::<Vec<_>>()
37+
};
38+
39+
let mut benches: Vec<BenchToRun> = vec![];
40+
for p in packages_to_run {
41+
let package_name = p.manifest().name().to_string();
42+
let package_target_dir = codspeed_target_dir.join(&package_name);
43+
let working_directory = p.root().to_path_buf();
44+
for entry in std::fs::read_dir(package_target_dir)? {
45+
let entry = entry?;
46+
let bench_path = entry.path();
47+
let bench_name = bench_path
48+
.file_name()
49+
.unwrap()
50+
.to_str()
51+
.unwrap()
52+
.to_string();
53+
if !bench_path.is_dir() {
54+
benches.push(BenchToRun {
55+
package_name: package_name.clone(),
56+
bench_path,
57+
bench_name,
58+
working_directory: working_directory.clone(),
59+
});
60+
}
61+
}
62+
}
63+
64+
if benches.is_empty() {
65+
if let Some(package) = package.as_ref() {
66+
bail!(
2067
"No benchmarks found. Run `cargo codspeed build -p {}` first.",
2168
package
22-
));
69+
);
70+
} else {
71+
bail!("No benchmarks found. Run `cargo codspeed build` first.");
2372
}
2473
}
25-
if !codspeed_dir.exists() {
26-
return Err(anyhow!(
27-
"No benchmarks found. Run `cargo codspeed build` first."
28-
));
29-
}
30-
31-
let found_benches = read_dir_recursive(codspeed_dir)?;
3274

33-
if found_benches.is_empty() {
34-
return Err(anyhow!(
35-
"No benchmark target found. Run `cargo codspeed build` first."
36-
));
37-
}
3875
let mut to_run = vec![];
39-
if let Some(benches) = benches {
76+
if let Some(selected_bench_names) = selected_bench_names {
4077
// Make sure all benchmarks are found
4178
let mut not_found = vec![];
42-
for bench in benches.iter() {
43-
let bench_path = found_benches
44-
.iter()
45-
.find(|b| b.file_name().unwrap().to_str().unwrap() == bench);
79+
for bench_name in selected_bench_names.iter() {
80+
let bench = benches.iter().find(|b| &b.bench_name == bench_name);
4681

47-
if let Some(bench_path) = bench_path {
48-
to_run.push(bench_path.clone());
82+
if let Some(bench) = bench {
83+
to_run.push(bench);
4984
} else {
50-
not_found.push(bench);
85+
not_found.push(bench_name);
5186
}
5287
}
5388

5489
if !not_found.is_empty() {
55-
return Err(anyhow!(
90+
bail!(
5691
"The following benchmarks to run were not found: {}",
5792
not_found.iter().join(", ")
58-
));
93+
);
5994
}
6095
} else {
61-
to_run = found_benches;
96+
to_run = benches.iter().collect();
6297
}
6398
ws.config().shell().status_with_color(
6499
"Collected",
65100
format!("{} benchmark suite(s) to run", to_run.len()),
66101
Color::White,
67102
)?;
68103
for bench in to_run.iter() {
69-
let bench_name = bench.file_name().unwrap().to_str().unwrap();
104+
let bench_name = &bench.bench_name;
70105
// workspace_root is needed since file! returns the path relatively to the workspace root
71106
// while CARGO_MANIFEST_DIR returns the path to the sub package
72107
let workspace_root = ws.root().to_string_lossy();
73108
ws.config()
74109
.shell()
75110
.status_with_color("Running", bench_name, Color::Yellow)?;
76-
std::process::Command::new(bench)
111+
std::process::Command::new(&bench.bench_path)
77112
.env("CODSPEED_CARGO_WORKSPACE_ROOT", workspace_root.as_ref())
113+
.current_dir(&bench.working_directory)
78114
.status()
79115
.map_err(|_| anyhow!("failed to execute the benchmark process"))
80116
.and_then(|status| {
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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[workspace]
2+
members = ["the_crate"]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "the_crate"
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+
[[bench]]
13+
name = "bench_example"
14+
harness = false
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std::collections::HashMap;
2+
3+
use codspeed::codspeed::black_box;
4+
use codspeed_bencher_compat::{benchmark_group, benchmark_main, Bencher};
5+
6+
pub fn a(bench: &mut Bencher) {
7+
// Open ./input.txt file
8+
std::fs::read_to_string("./input.txt").expect("Failed to read file");
9+
bench.iter(|| (0..100).fold(0, |x, y| black_box(x + y)))
10+
}
11+
12+
benchmark_group!(benches, a);
13+
benchmark_main!(benches);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello world!
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use predicates::str::contains;
2+
3+
mod helpers;
4+
use helpers::*;
5+
6+
const DIR: &str = "tests/crates_working_directory.in";
7+
8+
#[test]
9+
fn test_crates_working_directory_build_and_run_explicit() {
10+
let dir = setup(DIR, Project::CratesWorkingDirectory);
11+
cargo_codspeed(&dir)
12+
.args(["build", "-p", "the_crate"])
13+
.assert()
14+
.success();
15+
cargo_codspeed(&dir)
16+
.args(["run", "-p", "the_crate"])
17+
.assert()
18+
.success()
19+
.stderr(contains("Finished running 1 benchmark suite(s)"));
20+
teardown(dir);
21+
}
22+
23+
#[test]
24+
fn test_crates_working_directory_build_and_run_implicit() {
25+
let dir = setup(DIR, Project::CratesWorkingDirectory);
26+
cargo_codspeed(&dir)
27+
.args(["build", "-p", "the_crate"])
28+
.assert()
29+
.success();
30+
cargo_codspeed(&dir)
31+
.arg("run")
32+
.assert()
33+
.success()
34+
.stderr(contains("Finished running 1 benchmark suite(s)"));
35+
teardown(dir);
36+
}

crates/cargo-codspeed/tests/helpers.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub enum Project {
2121
Features,
2222
Workspace,
2323
PackageInDeps,
24+
CratesWorkingDirectory,
2425
}
2526

2627
pub fn setup(dir: &str, project: Project) -> String {
@@ -63,6 +64,17 @@ pub fn setup(dir: &str, project: Project) -> String {
6364
workspace_root.join("crates").to_str().unwrap(),
6465
);
6566
}
67+
Project::CratesWorkingDirectory => {
68+
replace_in_file(
69+
tmp_dir
70+
.join("the_crate")
71+
.join("Cargo.toml")
72+
.to_str()
73+
.unwrap(),
74+
"../../../..",
75+
workspace_root.join("crates").to_str().unwrap(),
76+
);
77+
}
6678
}
6779
tmp_dir.to_str().unwrap().to_string()
6880
}

0 commit comments

Comments
 (0)