Skip to main content

callisto_cli/
runner.rs

1use std::path::Path;
2use std::process::Stdio;
3
4use callisto_model::{CommandError, CommandOutput, CommandRunner};
5
6pub struct CliCommandRunner;
7
8impl CommandRunner for CliCommandRunner {
9    fn run(&self, program: &str, args: &[&str], cwd: &Path) -> Result<CommandOutput, CommandError> {
10        let output = std::process::Command::new(program)
11            .args(args)
12            .current_dir(cwd)
13            .stdin(Stdio::null())
14            .stdout(Stdio::piped())
15            .stderr(Stdio::piped())
16            .output();
17
18        match output {
19            Ok(o) => {
20                let out = CommandOutput {
21                    exit_code: o.status.code(),
22                    stdout: String::from_utf8_lossy(&o.stdout).into_owned(),
23                    stderr: String::from_utf8_lossy(&o.stderr).into_owned(),
24                };
25                if !out.stderr.is_empty() {
26                    eprint!("{}", out.stderr);
27                }
28                Ok(out)
29            }
30            Err(e) if e.kind() == std::io::ErrorKind::NotFound => Err(CommandError::NotFound {
31                program: program.to_string(),
32            }),
33            Err(e) => Err(CommandError::Io {
34                program: program.to_string(),
35                message: e.to_string(),
36            }),
37        }
38    }
39}