1#[macro_use]
2extern crate failure;
3
4use failure::Error;
5use std::process::Command;
6use std::process::Output;
7
8#[derive(Fail, Debug)]
10#[fail(display = "Command failed: {}, output: {:?}", command, output)]
11pub struct CommandFail {
12 command: String,
13 output: Output,
14}
15
16impl CommandFail {
17 pub fn command(&self) -> &str {
19 &self.command
20 }
21
22 pub fn output(&self) -> &Output {
24 &self.output
25 }
26}
27
28type Result<T> = std::result::Result<T, Error>;
29
30pub fn run_shell_command(cmd: &str) -> Result<String> {
32 let output = if cfg!(target_os = "windows") {
33 Command::new("cmd").arg("/C").arg(cmd).output()?
35 } else {
36 Command::new("sh").arg("-c").arg(cmd).output()?
37 };
38 if output.status.success() {
39 Ok(String::from_utf8(output.stdout)?)
40 } else {
41 Err(CommandFail {
42 command: cmd.into(),
43 output,
44 }
45 .into())
46 }
47}