use std::path::{Path, PathBuf};
use git2::Repository;
use ironflow_core::error::OperationError;
use crate::helpers::git_error;
#[derive(Debug, Clone)]
pub struct GitRepo {
path: PathBuf,
}
impl GitRepo {
pub fn open(path: impl AsRef<Path>) -> Result<Self, OperationError> {
let path = path.as_ref().to_path_buf();
let repo = Repository::open(&path).map_err(git_error)?;
let workdir = repo
.workdir()
.map(Path::to_path_buf)
.unwrap_or_else(|| path.clone());
Ok(Self { path: workdir })
}
pub fn from_path(path: impl Into<PathBuf>) -> Self {
Self { path: path.into() }
}
pub fn path(&self) -> &Path {
&self.path
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn open_valid_repo() {
let tmp = tempfile::tempdir().unwrap();
Repository::init(tmp.path()).unwrap();
let repo = GitRepo::open(tmp.path()).unwrap();
assert!(repo.path().exists());
assert!(repo.path().join(".git").exists());
}
#[test]
fn open_invalid_path() {
let err = GitRepo::open("/nonexistent/path/to/repo").unwrap_err();
let msg = err.to_string();
assert!(msg.contains("git error"), "got: {msg}");
}
}