use crate::utils::{Error, Result, INTERNAL_ERR};
use oclif::term::TERM_ERR;
use std::{
io::{BufRead, BufReader},
path::PathBuf,
process::{Command, Stdio},
};
pub fn cargo<'a>(root: &PathBuf, args: &[&'a str], out: bool) -> Result<(String, String)> {
let mut args = args.to_vec();
if TERM_ERR.features().colors_supported() {
args.push("--color");
args.push("always");
}
eprintln!();
let mut output_stderr = vec![];
let mut child = Command::new("cargo")
.current_dir(root)
.args(&args)
.stderr(Stdio::piped())
.spawn()
.map_err(|err| Error::Cargo {
err,
args: args.iter().map(|x| x.to_string()).collect(),
})?;
{
let stderr = child.stderr.as_mut().expect(INTERNAL_ERR);
for line in BufReader::new(stderr).lines() {
let line = line?;
if out {
eprintln!("{}", line);
}
output_stderr.push(line);
}
}
let output = child.wait_with_output().map_err(|err| Error::Cargo {
err,
args: args.iter().map(|x| x.to_string()).collect(),
})?;
eprintln!();
Ok((
String::from_utf8(output.stdout)?.trim().to_owned(),
output_stderr.join("\n").trim().to_owned(),
))
}