Skip to content

Commit 6990ef0

Browse files
Merge pull request #1104 from rylev/diff_local-error-handling
Add more robust error handling for diff_local
2 parents d5a4428 + 8edaa2d commit 6990ef0

File tree

2 files changed

+48
-19
lines changed

2 files changed

+48
-19
lines changed

collector/src/lib.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,12 @@ pub fn robocopy(
186186
}
187187

188188
fn run_command_with_output(cmd: &mut Command) -> anyhow::Result<process::Output> {
189-
let mut child = cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).spawn()?;
189+
use anyhow::Context;
190+
let mut child = cmd
191+
.stdout(Stdio::piped())
192+
.stderr(Stdio::piped())
193+
.spawn()
194+
.with_context(|| format!("failed to spawn process for cmd: {:?}", cmd))?;
190195

191196
let mut stdout = Vec::new();
192197
let mut stderr = Vec::new();
@@ -213,7 +218,9 @@ fn run_command_with_output(cmd: &mut Command) -> anyhow::Result<process::Output>
213218
},
214219
)?;
215220

216-
let status = child.wait()?;
221+
let status = child
222+
.wait()
223+
.with_context(|| "failed to wait on child process")?;
217224

218225
Ok(process::Output {
219226
status,

collector/src/main.rs

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -321,18 +321,25 @@ fn bench(
321321
}
322322

323323
fn check_measureme_installed() -> Result<(), String> {
324-
let mut binaries = vec![];
325-
326-
for name in ["summarize", "crox", "flamegraph"] {
327-
if let Err(_) = Command::new(name).output() {
328-
binaries.push(name);
329-
}
330-
}
331-
if binaries.is_empty() {
324+
let not_installed = std::array::IntoIter::new(["summarize", "crox", "flamegraph"])
325+
.filter(|n| !is_installed(n))
326+
.collect::<Vec<_>>();
327+
if not_installed.is_empty() {
332328
Ok(())
333329
} else {
334-
Err(format!("To run this command you need {0} on your PATH. To install run `cargo install --git https://github.com/rust-lang/measureme --branch stable {0}`\n", binaries.join(" ")))
330+
Err(format!("To run this command you need {0} on your PATH. To install run `cargo install --git https://github.com/rust-lang/measureme --branch stable {0}`\n", not_installed.join(" ")))
331+
}
332+
}
333+
334+
fn check_installed(name: &str) -> anyhow::Result<()> {
335+
if !is_installed(name) {
336+
anyhow::bail!("`{}` is not installed but must be", name);
335337
}
338+
Ok(())
339+
}
340+
341+
fn is_installed(name: &str) -> bool {
342+
Command::new(name).output().is_ok()
336343
}
337344

338345
fn get_benchmarks(
@@ -490,14 +497,19 @@ fn get_local_toolchain(
490497
.with_context(|| format!("failed to canonicalize cargo executable '{}'", cargo))?
491498
} else {
492499
// Use the nightly cargo from `rustup`.
493-
let s = String::from_utf8(
494-
Command::new("rustup")
495-
.args(&["which", "cargo", "--toolchain=nightly"])
496-
.output()
497-
.context("failed to run `rustup which cargo`")?
498-
.stdout,
499-
)
500-
.context("failed to convert `rustup which cargo` output to utf8")?;
500+
let output = Command::new("rustup")
501+
.args(&["which", "cargo", "--toolchain=nightly"])
502+
.output()
503+
.context("failed to run `rustup which cargo`")?;
504+
if !output.status.success() {
505+
anyhow::bail!(
506+
"`rustup which cargo` exited with status {}\nstderr={}",
507+
output.status,
508+
String::from_utf8_lossy(&output.stderr)
509+
)
510+
}
511+
let s = String::from_utf8(output.stdout)
512+
.context("failed to convert `rustup which cargo` output to utf8")?;
501513

502514
let cargo = PathBuf::from(s.trim());
503515
debug!("found cargo: {:?}", &cargo);
@@ -576,6 +588,9 @@ fn generate_cachegrind_diffs(
576588

577589
/// Demangles symbols in a file using rustfilt and writes result to path.
578590
fn rustfilt(cgout: &Path, path: &Path) -> anyhow::Result<()> {
591+
if !is_installed("rustfilt") {
592+
anyhow::bail!("`rustfilt` not installed.");
593+
}
579594
let output = Command::new("rustfilt")
580595
.arg("-i")
581596
.arg(cgout)
@@ -594,6 +609,9 @@ fn rustfilt(cgout: &Path, path: &Path) -> anyhow::Result<()> {
594609

595610
/// Compares two Cachegrind output files using cg_diff and writes result to path.
596611
fn cg_diff(cgout1: &Path, cgout2: &Path, path: &Path) -> anyhow::Result<()> {
612+
if !is_installed("cg_diff") {
613+
anyhow::bail!("`cg_diff` not installed.");
614+
}
597615
let output = Command::new("cg_diff")
598616
.arg("--mod-filename=s#/rustc/[^/]*/##")
599617
.arg("--mod-funcname=s/[.]llvm[.].*//")
@@ -1042,6 +1060,10 @@ fn main_result() -> anyhow::Result<i32> {
10421060
let out_dir = PathBuf::from(sub_m.value_of_os("OUT_DIR").unwrap_or(default_out_dir));
10431061
let scenario_kinds = scenario_kinds_from_arg(sub_m.value_of("RUNS"))?;
10441062
let rustdoc = sub_m.value_of("RUSTDOC");
1063+
check_installed("valgrind")?;
1064+
check_installed("cg_annotate")?;
1065+
check_installed("rustup-toolchain-install-master")?;
1066+
check_installed("rustfilt")?;
10451067

10461068
let id1 = rustc1.strip_prefix('+').unwrap_or("before");
10471069
let id2 = rustc2.strip_prefix('+').unwrap_or("after");

0 commit comments

Comments
 (0)