cargo_codesign/
subprocess.rs1use std::process::Command;
2
3#[derive(Debug)]
4pub struct RunOutput {
5 pub stdout: String,
6 pub stderr: String,
7 pub success: bool,
8 pub code: Option<i32>,
9}
10
11#[derive(Debug, thiserror::Error)]
12pub enum SubprocessError {
13 #[error("failed to execute {command}: {source}")]
14 SpawnFailed {
15 command: String,
16 source: std::io::Error,
17 },
18}
19
20pub fn run(command: &str, args: &[&str], verbose: bool) -> Result<RunOutput, SubprocessError> {
21 if verbose {
22 eprintln!(" $ {} {}", command, args.join(" "));
23 }
24
25 let output =
26 Command::new(command)
27 .args(args)
28 .output()
29 .map_err(|e| SubprocessError::SpawnFailed {
30 command: command.to_string(),
31 source: e,
32 })?;
33
34 let stdout = String::from_utf8_lossy(&output.stdout).to_string();
35 let stderr = String::from_utf8_lossy(&output.stderr).to_string();
36
37 if verbose && !stdout.is_empty() {
38 eprint!("{stdout}");
39 }
40 if verbose && !stderr.is_empty() {
41 eprint!("{stderr}");
42 }
43
44 Ok(RunOutput {
45 stdout,
46 stderr,
47 success: output.status.success(),
48 code: output.status.code(),
49 })
50}