1use indexmap::IndexMap;
9use vantage_core::{Result, error};
10
11#[derive(Clone, Debug)]
13pub struct CmdOutput {
14 pub stdout: String,
15 pub stderr: String,
16 pub exit_code: i32,
17}
18
19pub fn run_command(
23 command: &str,
24 args: &[String],
25 env: &IndexMap<String, String>,
26 pass_path: bool,
27) -> Result<CmdOutput> {
28 let mut cmd = std::process::Command::new(command);
29 cmd.args(args);
30 cmd.env_clear();
31
32 if pass_path {
33 if let Ok(path) = std::env::var("PATH") {
34 cmd.env("PATH", path);
35 }
36 if let Ok(home) = std::env::var("HOME") {
37 cmd.env("HOME", home);
38 }
39 }
40 for (k, v) in env {
41 cmd.env(k, v);
42 }
43
44 let output = cmd.output().map_err(|e| {
45 error!(
46 "failed to execute command",
47 command = command.to_string(),
48 detail = e.to_string()
49 )
50 })?;
51
52 Ok(CmdOutput {
53 stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
54 stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
55 exit_code: output.status.code().unwrap_or(-1),
56 })
57}