use std::fs;
use anyhow::Result;
use crate::{cli::banner, cli::output::*, git::GitRepo};
pub async fn uninstall_hooks(hooks: Option<Vec<String>>, force: bool) -> Result<()> {
uninstall_hooks_at(hooks, force, None).await
}
pub async fn uninstall_hooks_at(
hooks: Option<Vec<String>>,
force: bool,
repo_path: Option<&std::path::Path>,
) -> Result<()> {
banner::print_banner(None);
let repo = match repo_path {
Some(path) => match GitRepo::open(path) {
Ok(repo) => repo,
Err(_) => {
error!(&format!("Not a git repository: {}", path.display()));
return Ok(());
}
},
None => match GitRepo::discover() {
Ok(repo) => repo,
Err(_) => {
error!("Not in a git repository");
return Ok(());
}
},
};
let hooks_dir = repo.git_dir().join("hooks");
let hook_names: Vec<String> = hooks.unwrap_or_else(|| {
vec![
"pre-commit".to_string(),
"commit-msg".to_string(),
"post-checkout".to_string(),
"pre-push".to_string(),
]
});
let mut guardy_hooks = Vec::new();
for hook_name in &hook_names {
let hook_path = hooks_dir.join(hook_name);
if hook_path.exists()
&& let Ok(content) = fs::read_to_string(&hook_path)
&& content.contains("guardy hooks run")
{
guardy_hooks.push((hook_name.clone(), hook_path));
}
}
if guardy_hooks.is_empty() {
info!("No guardy hooks found to remove");
return Ok(());
}
if !force {
warning!(&format!(
"This will remove {} guardy hooks:",
guardy_hooks.len()
));
for (hook_name, _) in &guardy_hooks {
println!(" - {hook_name}");
}
print!("Are you sure you want to continue? [y/N]: ");
std::io::Write::flush(&mut std::io::stdout())?;
let mut input = String::new();
std::io::stdin().read_line(&mut input)?;
let input = input.trim().to_lowercase();
if input != "y" && input != "yes" {
info!("Uninstall cancelled");
return Ok(());
}
}
info!("Removing guardy hooks...");
let mut removed_count = 0;
for (hook_name, hook_path) in guardy_hooks {
match fs::remove_file(&hook_path) {
Ok(_) => {
success!(&format!("Removed '{hook_name}' hook"));
removed_count += 1;
}
Err(e) => {
error!(&format!("Failed to remove '{hook_name}' hook: {e}"));
}
}
}
if removed_count > 0 {
success!(&format!(
"Successfully removed {removed_count} guardy hooks"
));
} else {
warning!("No hooks were removed");
}
Ok(())
}