1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use std::process::{Child, Command, Stdio};

pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> Result<String, String> {
  Command::new(cmd)
    .args(args)
    .stdout(stdout)
    .output()
    .map_err(|err| err.to_string())
    .and_then(|output| {
      if output.status.success() {
        Result::Ok(String::from_utf8_lossy(&output.stdout).to_string())
      } else {
        Result::Err(String::from_utf8_lossy(&output.stderr).to_string())
      }
    })
}

pub fn format_command(path: String, command: String) -> String {
  if cfg!(windows) {
    format!("{}/./{}.exe", path, command)
  } else {
    format!("{}/./{}", path, command)
  }
}

pub fn relative_command(command: String) -> Result<String, std::io::Error> {
  match std::env::current_exe()?.parent() {
    Some(exe_dir) => return Ok(format_command(exe_dir.display().to_string(), command)),
    None => {
      return Err(std::io::Error::new(
        std::io::ErrorKind::Other,
        "Could not evaluate executable dir".to_string(),
      ))
    }
  }
}

pub fn command_path(command: String) -> Result<String, std::io::Error> {
  match std::env::current_exe()?.parent() {
    #[cfg(not(windows))]
    Some(exe_dir) => Ok(format!("{}/{}", exe_dir.display().to_string(), command)),
    #[cfg(windows)]
    Some(exe_dir) => Ok(format!("{}/{}.exe", exe_dir.display().to_string(), command)),
    None => Err(std::io::Error::new(
      std::io::ErrorKind::Other,
      "Could not evaluate executable dir".to_string(),
    )),
  }
}

pub fn spawn_relative_command(
  command: String,
  args: Vec<String>,
  stdout: Stdio,
) -> Result<Child, std::io::Error> {
  let cmd = relative_command(command)?;
  Ok(Command::new(cmd).args(args).stdout(stdout).spawn()?)
}