use std::path::Path;
use tokio::process::Command;
pub(crate) struct GitRepo {
pub dir: tempfile::TempDir,
}
impl GitRepo {
pub async fn init() -> Self {
let dir = tempfile::Builder::new()
.prefix("drep-diff-test-")
.tempdir()
.expect("tempdir");
let root = dir.path();
for argv in [
vec!["init", "--quiet", "-b", "main"],
vec!["config", "user.email", "drep@example.com"],
vec!["config", "user.name", "drep"],
] {
run_in(root, &argv).await;
}
let repo = Self { dir };
repo.commit_all("initial").await;
repo
}
pub async fn init_no_commits() -> Self {
let dir = tempfile::Builder::new()
.prefix("drep-diff-test-")
.tempdir()
.expect("tempdir");
let root = dir.path();
for argv in [
vec!["init", "--quiet", "-b", "main"],
vec!["config", "user.email", "drep@example.com"],
vec!["config", "user.name", "drep"],
] {
run_in(root, &argv).await;
}
Self { dir }
}
pub async fn commit_all(&self, message: &str) {
let root = self.dir.path();
run_in(root, &["add", "."]).await;
run_in(
root,
&[
"-c",
"commit.gpgsign=false",
"commit",
"--quiet",
"--allow-empty",
"-m",
message,
],
)
.await;
}
pub async fn create_branch(&self, branch: &str) {
run_in(self.dir.path(), &["branch", branch]).await;
}
pub async fn checkout(&self, branch: &str) {
run_in(self.dir.path(), &["checkout", "--quiet", branch]).await;
}
pub fn root(&self) -> &Path {
self.dir.path()
}
}
pub(crate) async fn run_in(root: &Path, args: &[&str]) {
let mut command = Command::new("git");
command.args(args).current_dir(root);
let output = command.output().await.expect("spawn git");
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
panic!("git {args:?} in {} failed: {stderr}", root.display());
}
}