use std::path::{Path, PathBuf};
use std::process::{Command, Output};
use anyhow::{Context, Result, bail};
pub struct Git {
dir: PathBuf,
}
impl Git {
pub fn new(dir: impl Into<PathBuf>) -> Self {
Git { dir: dir.into() }
}
pub fn dir(&self) -> &Path {
&self.dir
}
pub fn run(&self, args: &[&str]) -> Result<String> {
let output = self.output(args)?;
if !output.status.success() {
bail!(
"git {} failed: {}",
args.join(" "),
String::from_utf8_lossy(&output.stderr).trim()
);
}
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}
pub fn succeeds(&self, args: &[&str]) -> Result<bool> {
Ok(self.output(args)?.status.success())
}
fn output(&self, args: &[&str]) -> Result<Output> {
Command::new("git")
.args(args)
.current_dir(&self.dir)
.output()
.with_context(|| format!("could not run git {}", args.join(" ")))
}
}