use std::io;
use std::io::Write;
use std::process::{Command, ExitStatus};
use errors::*;
pub trait CommandExt {
fn run(&mut self, verbose: bool) -> Result<()>;
fn run_and_get_status(&mut self, verbose: bool) -> Result<ExitStatus>;
fn run_and_get_stdout(&mut self, verbose: bool) -> Result<String>;
}
impl CommandExt for Command {
fn run(&mut self, verbose: bool) -> Result<()> {
let status = self.run_and_get_status(verbose)?;
if status.success() {
Ok(())
} else {
Err(format!(
"`{:?}` failed with exit code: {:?}",
self,
status.code()
))?
}
}
fn run_and_get_status(&mut self, verbose: bool) -> Result<ExitStatus> {
if verbose {
writeln!(io::stderr(), "+ {:?}", self).ok();
}
self.status()
.chain_err(|| format!("couldn't execute `{:?}`", self))
}
fn run_and_get_stdout(&mut self, verbose: bool) -> Result<String> {
if verbose {
writeln!(io::stderr(), "+ {:?}", self).ok();
}
let out = self
.output()
.chain_err(|| format!("couldn't execute `{:?}`", self))?;
if out.status.success() {
Ok(String::from_utf8(out.stdout)
.chain_err(|| format!("`{:?}` output was not UTF-8", self))?)
} else {
Err(format!(
"`{:?}` failed with exit code: {:?}",
self,
out.status.code()
))?
}
}
}