1use crate::error::Error;
2use std::error::Error as StdError;
3use std::ffi::OsStr;
4use std::io;
5use std::process::{Child, Command, Stdio};
6
7pub const PANIC_MSG: &str = "Shell execution failed";
8
9pub fn spawn<TArg, TEnvKey, TEnvVal>(
10 cmd: impl AsRef<OsStr>,
11 args: impl IntoIterator<Item = TArg>,
12 envs: impl IntoIterator<Item = (TEnvKey, TEnvVal)>,
13) -> Result<Child, io::Error>
14where
15 TArg: AsRef<OsStr>,
16 TEnvKey: AsRef<OsStr>,
17 TEnvVal: AsRef<OsStr>,
18{
19 Command::new(cmd)
20 .stdout(Stdio::piped())
21 .args(args)
22 .envs(envs)
23 .spawn()
24}
25
26pub fn check_exit_code<E: StdError>(process: Child) -> Result<(), Error<E>> {
27 let output = process.wait_with_output().map_err(Error::WaitFailed)?;
28
29 if !output.status.success() {
30 Err(Error::ProcessFailed(output))
31 } else {
32 Ok(())
33 }
34}
35
36pub fn check_exit_code_panic(process: Child) {
37 let output = process.wait_with_output().expect(PANIC_MSG);
38
39 if !output.status.success() {
40 panic!("{}", PANIC_MSG)
41 }
42}