Skip to main content

cargo_codesign/
subprocess.rs

1use 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}