use std::path::{Path, PathBuf};
use std::process::{Command, Output};
use tempfile::TempDir;
pub struct TempGitRepo {
pub dir: TempDir,
pub remote_dir: TempDir,
}
impl TempGitRepo {
pub fn new() -> Self {
let remote_dir = TempDir::new().expect("Failed to create remote temp directory");
let dir = TempDir::new().expect("Failed to create temp directory");
Command::new("git")
.args(["init", "--bare", "-b", "main"])
.current_dir(remote_dir.path())
.output()
.expect("Failed to initialize bare repo");
let repo = Self { dir, remote_dir };
repo.git(&["init", "-b", "main"]);
repo.git(&["config", "user.name", "Test User"]);
repo.git(&["config", "user.email", "test@example.com"]);
let remote_path = repo.remote_dir.path().to_str().unwrap();
repo.git(&["remote", "add", "origin", remote_path]);
repo.write_file("README.md", "# Test Repository");
repo.git(&["add", "."]);
repo.git(&["commit", "-m", "Initial commit"]);
repo.git(&["push", "-u", "origin", "main"]);
repo
}
pub fn path(&self) -> &Path {
self.dir.path()
}
pub fn git(&self, args: &[&str]) -> Output {
let output = Command::new("git")
.args(args)
.current_dir(self.path())
.output()
.expect("Failed to execute git command");
if !output.status.success() {
panic!(
"Git command failed: git {}\nstderr: {}",
args.join(" "),
String::from_utf8_lossy(&output.stderr)
);
}
output
}
pub fn write_file(&self, name: &str, content: &str) {
let path = self.path().join(name);
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).expect("Failed to create parent directories");
}
std::fs::write(&path, content).expect("Failed to write file");
}
pub fn commit(&self, message: &str) {
self.git(&["commit", "-m", message]);
}
pub fn create_branch(&self, name: &str) {
self.git(&["checkout", "-b", name]);
}
pub fn switch_branch(&self, name: &str) {
self.git(&["switch", name]);
}
pub fn current_branch(&self) -> String {
let output = self.git(&["rev-parse", "--abbrev-ref", "HEAD"]);
String::from_utf8_lossy(&output.stdout).trim().to_string()
}
pub fn cresca_binary() -> PathBuf {
assert_cmd::cargo::cargo_bin!("cresca").to_path_buf()
}
pub fn run_cresca(&self, args: &[&str]) -> Output {
Command::new(Self::cresca_binary())
.args(args)
.current_dir(self.path())
.output()
.expect("Failed to execute cresca")
}
pub fn has_uncommitted_changes(&self) -> bool {
let output = self.git(&["status", "--porcelain"]);
!output.stdout.is_empty()
}
}