use crate::Error;
use std::path::{Path, PathBuf};
use which::which;
fn get_absolute_executable_path() -> Result<PathBuf, Error> {
let arg0 = std::env::args().next().unwrap();
let path = std::path::PathBuf::from(arg0.clone());
if let Some(name) = path.file_name()
&& name.to_str() == Some(arg0.as_str())
{
which(&arg0).map_err(|_| Error::UnableToDetermineYactPath)
} else if path.is_absolute() {
Ok(path)
} else if path.is_relative() {
Ok(path.canonicalize()?)
} else {
Err(Error::UnableToDetermineYactPath)
}
}
pub fn init<P: AsRef<Path>>(repository_path: P, force: bool) -> Result<(), Error> {
let hook_path = repository_path
.as_ref()
.join(".git")
.join("hooks")
.join("pre-commit");
if hook_path.exists() {
if force {
std::fs::remove_file(&hook_path)?;
} else {
return Err(Error::PreCommitHookAlreadyExists);
}
}
let executable_path = get_absolute_executable_path()?;
#[cfg(target_family = "unix")]
std::os::unix::fs::symlink(executable_path, hook_path)?;
#[cfg(not(target_family = "unix"))]
std::fs::hard_link(executable_path, hook_path)?;
Ok(())
}