Skip to main content

open_envault/
runtime.rs

1use anyhow::bail;
2use std::{
3    collections::BTreeMap,
4    process::{Command, Stdio},
5};
6pub fn exec(
7    command: &[String],
8    values: &BTreeMap<String, String>,
9    force: bool,
10) -> anyhow::Result<i32> {
11    let Some(program) = command.first() else {
12        bail!("a child command is required after --")
13    };
14    let mut child = Command::new(program);
15    child
16        .args(&command[1..])
17        .stdin(Stdio::inherit())
18        .stdout(Stdio::inherit())
19        .stderr(Stdio::inherit());
20    if force {
21        child.envs(values);
22    } else {
23        for (name, value) in values {
24            if std::env::var_os(name).is_none() {
25                child.env(name, value);
26            }
27        }
28    }
29    let status = child.status()?;
30    Ok(status.code().unwrap_or(128 + status.signal().unwrap_or(0)))
31}
32trait SignalCode {
33    fn signal(&self) -> Option<i32>;
34}
35impl SignalCode for std::process::ExitStatus {
36    fn signal(&self) -> Option<i32> {
37        #[cfg(unix)]
38        {
39            std::os::unix::process::ExitStatusExt::signal(self)
40        }
41        #[cfg(not(unix))]
42        {
43            None
44        }
45    }
46}