32 lines
960 B
Rust
32 lines
960 B
Rust
use std::process::Command;
|
|
|
|
use anyhow::{Context, anyhow, bail};
|
|
|
|
/// Spawn a subprocess with arguments.
|
|
///
|
|
/// Collects `stdout` and returns it on success.
|
|
/// Returns `Err` if the exit code isn't 0, or if the process failed to spawn.
|
|
pub fn cmd(cmd: &[&str]) -> anyhow::Result<String> {
|
|
let [cmd, args @ ..] = cmd else {
|
|
bail!("missing command");
|
|
};
|
|
|
|
let mut command = Command::new(cmd);
|
|
command.args(args);
|
|
println!("$ {command:?}");
|
|
let output = command
|
|
.output()
|
|
.with_context(|| anyhow!("Failed to run {command:?}"))?;
|
|
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
if !output.status.success() {
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
eprintln!("{command:?} failed");
|
|
eprintln!("stdout:\n{stdout}\n");
|
|
eprintln!("stderr:\n{stderr}\n");
|
|
bail!("{command:?} failed with exit code {}", output.status);
|
|
}
|
|
|
|
Ok(stdout.to_string())
|
|
}
|