oxdock_process/
shell.rs

1use anyhow::{Context, Result, bail};
2use std::ffi::OsStr;
3use std::fs::File;
4#[allow(clippy::disallowed_types, clippy::disallowed_methods)]
5use std::process::{Command, ExitStatus, Stdio};
6
7pub fn shell_program() -> String {
8    #[cfg(windows)]
9    {
10        std::env::var("COMSPEC").unwrap_or_else(|_| "cmd".to_string())
11    }
12
13    #[cfg(not(windows))]
14    {
15        std::env::var("SHELL").unwrap_or_else(|_| "sh".to_string())
16    }
17}
18
19#[allow(clippy::disallowed_types, clippy::disallowed_methods)]
20pub(crate) fn shell_cmd(cmd: &str) -> Command {
21    let program = shell_program();
22    let mut c = Command::new(program);
23    #[allow(clippy::disallowed_macros)]
24    if cfg!(windows) {
25        c.arg("/C").arg(cmd);
26    } else {
27        c.arg("-c").arg(cmd);
28    }
29    c
30}
31
32#[derive(Default)]
33pub struct ShellLauncher;
34
35#[allow(clippy::disallowed_types, clippy::disallowed_methods)]
36impl ShellLauncher {
37    pub fn run(&self, cmd: &mut Command) -> Result<()> {
38        let status = cmd
39            .status()
40            .with_context(|| format!("failed to run {:?}", cmd))?;
41        if !status.success() {
42            bail!("command {:?} failed with status {}", cmd, status);
43        }
44        Ok(())
45    }
46
47    pub fn run_with_output(&self, cmd: &mut Command) -> Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
48        cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
49        let output = cmd
50            .output()
51            .with_context(|| format!("failed to run {:?}", cmd))?;
52        Ok((output.status, output.stdout, output.stderr))
53    }
54
55    pub fn spawn(&self, cmd: &mut Command) -> Result<()> {
56        cmd.spawn()
57            .with_context(|| format!("failed to spawn {:?}", cmd))?;
58        Ok(())
59    }
60
61    pub fn with_stdins<'a>(&self, cmd: &'a mut Command, stdin: Option<File>) -> &'a mut Command {
62        if let Some(file) = stdin {
63            cmd.stdin(file);
64        }
65        cmd
66    }
67
68    pub fn program_arg(&self, program: impl AsRef<OsStr>) -> Command {
69        Command::new(program)
70    }
71}