use std::path::{Path, PathBuf};
use git2::Repository;
use miette::{IntoDiagnostic, Result};
pub fn resolve_commit_message_path(
provided: Option<PathBuf>,
current_dir: &Path,
) -> Result<PathBuf> {
if let Some(path) = provided {
Ok(path)
} else {
let repo = Repository::discover(current_dir).into_diagnostic()?;
Ok(repo.path().join("COMMIT_EDITMSG"))
}
}
#[cfg(test)]
mod tests {
use std::fs;
use std::path::{Path, PathBuf};
use super::resolve_commit_message_path;
use git2::Repository;
use tempfile::TempDir;
#[test]
fn returns_provided_path_unchanged() {
let provided = PathBuf::from("/some/arbitrary/path");
let result = resolve_commit_message_path(Some(provided.clone()), Path::new("/tmp"));
assert_eq!(result.unwrap(), provided);
}
#[test]
fn defaults_to_commit_editmsg_when_not_provided() {
let temp = TempDir::new().unwrap();
let repo = Repository::init(temp.path()).unwrap();
let expected = repo.path().join("COMMIT_EDITMSG");
let result = resolve_commit_message_path(None, temp.path());
assert_eq!(result.unwrap(), expected);
}
#[test]
fn discovers_repo_from_subdirectory() {
let temp = TempDir::new().unwrap();
let repo = Repository::init(temp.path()).unwrap();
let expected = repo.path().join("COMMIT_EDITMSG");
let subdir = temp.path().join("nested/deep");
fs::create_dir_all(&subdir).unwrap();
let result = resolve_commit_message_path(None, &subdir);
assert_eq!(result.unwrap(), expected);
}
#[test]
fn errors_when_not_in_git_repo_and_not_provided() {
let temp = TempDir::new().unwrap();
let result = resolve_commit_message_path(None, temp.path());
assert!(result.is_err());
}
}