use std::path::Path;
use std::process::Command;
use tempfile::TempDir;
pub type TestResult<T = ()> = Result<T, Box<dyn std::error::Error>>;
pub fn run_git_command(args: &[&str], cwd: &Path) -> TestResult {
let output = Command::new("git")
.args(args)
.current_dir(cwd)
.output()
.map_err(|e| format!("Failed to run git command: {}", e))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(format!("Git command failed: {}", stderr).into());
}
Ok(())
}
#[allow(dead_code)]
pub async fn ensure_empty_repository_and_commit(path: &Path) -> TestResult {
ensure_empty_repository(path).await?;
commit(path).await
}
pub async fn ensure_empty_repository(path: &Path) -> TestResult {
std::fs::create_dir_all(path).map_err(|e| format!("Failed to create directory: {}", e))?;
run_git_command(&["init", "--initial-branch=main"], path)?;
run_git_command(&["config", "user.email", "test@example.com"], path)?;
run_git_command(&["config", "user.name", "Test User"], path)?;
run_git_command(&["config", "commit.gpgsign", "false"], path)?;
Ok(())
}
#[allow(dead_code)]
pub async fn commit(path: &Path) -> TestResult {
run_git_command(&["commit", "--allow-empty", "-m", "."], path)
}
#[allow(dead_code)]
pub async fn tag(path: &Path, tag_name: &str) -> TestResult {
run_git_command(&["tag", tag_name], path)
}
#[allow(dead_code)]
pub async fn annotated_tag(path: &Path, tag_name: &str, message: &str) -> TestResult {
run_git_command(&["tag", "-a", tag_name, "-m", message], path)
}
#[allow(dead_code)]
pub async fn checkout(path: &Path, ref_name: &str) -> TestResult {
run_git_command(&["checkout", ref_name], path)
}
#[allow(dead_code)]
pub async fn get_commit_shas(path: &Path) -> TestResult<Vec<String>> {
let output = Command::new("git")
.args(["log", "--pretty=format:%H"])
.current_dir(path)
.output()
.map_err(|e| format!("Failed to run git log: {}", e))?;
let stdout = String::from_utf8_lossy(&output.stdout);
let shas: Vec<String> = stdout
.lines()
.filter(|line| !line.is_empty())
.map(|line| line.to_string())
.collect();
Ok(shas)
}
#[allow(dead_code)]
pub async fn get_graph(path: &Path) -> TestResult<String> {
let output = Command::new("git")
.args(["log", "--graph", "--pretty=format:'%d'"])
.current_dir(path)
.output()
.map_err(|e| format!("Failed to run git log: {}", e))?;
let stdout = String::from_utf8_lossy(&output.stdout);
Ok(stdout.to_string())
}
#[allow(dead_code)]
pub fn get_test_directory(_test_name: &str) -> TempDir {
let _run_id = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
tempfile::tempdir().expect("Failed to create temp directory")
}