Skip to main content

task_commander/
command.rs

1use super::errors::{Result, err_command_spawn};
2use std::ffi::OsStr;
3use std::path::Path;
4use std::process::{Command, ExitStatus, Stdio};
5
6/// Executes a given command in shell.
7///
8/// # Errors
9///
10/// (tbd)
11///
12/// # Panics
13///
14/// TODO Get rid of panics
15pub fn execute(arg: impl AsRef<OsStr>, dir: impl AsRef<Path>) -> Result<ExitStatus> {
16    let mut command = Command::new(get_shell_command());
17    let mut child = command
18        .args(get_shell_args())
19        .arg(arg)
20        .current_dir(dir)
21        .stdin(Stdio::inherit())
22        .stdout(Stdio::inherit())
23        .stderr(Stdio::inherit())
24        .spawn()
25        .map_err(|e| err_command_spawn(e.to_string()))?;
26    // It is rare for the following command to fail.
27    // If it does, let the code panic.
28    Ok(child.wait().expect("failed to wait for child process"))
29}
30
31/// Returns a shell command specific for the operating system.
32#[cfg(target_os = "macos")]
33const fn get_shell_command() -> &'static str {
34    "/bin/zsh"
35}
36
37#[cfg(target_os = "linux")]
38fn get_shell_command() -> &'static str {
39    "/bin/sh"
40}
41
42#[cfg(target_os = "windows")]
43fn get_shell_command() -> &'static str {
44    "cmd"
45}
46
47/// Returns options required by a shell command.
48#[cfg(unix)]
49const fn get_shell_args() -> &'static [&'static str] {
50    &["-c"]
51}
52
53#[cfg(target_os = "windows")]
54fn get_shell_args() -> &'static [&'static str] {
55    &["/c"]
56}