use anyhow::{anyhow, Result};
use colored::Colorize;
use std::{path::Path, process::Command};
pub fn git_diff() -> Result<String> {
let output = Command::new("git")
.arg("diff-index")
.arg("HEAD")
.arg("--stat")
.arg("-p")
.output()
.expect("failed to execute process");
let stdout = String::from_utf8(output.stdout)?;
Ok(stdout)
}
pub fn install_git_hook(hooks_dir: &Path) -> Result<()> {
std::fs::create_dir_all(hooks_dir)?;
let hook_path = hooks_dir.join("prepare-commit-msg");
let current_exe = std::env::current_exe()?;
let hook_binary = current_exe
.parent()
.ok_or_else(|| anyhow!("Cannot determine executable directory"))?
.join("gitai-hook");
let hook_content = format!(
r#"#!/bin/sh
# Generated by slf gitai
exec {} "$@""#,
hook_binary.display()
);
std::fs::write(&hook_path, hook_content)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = std::fs::metadata(&hook_path)?.permissions();
perms.set_mode(0o755);
std::fs::set_permissions(&hook_path, perms)?;
}
println!("{}", "Git hook installed successfully.".green());
Ok(())
}
pub fn remove_git_hook(hooks_dir: &Path) -> Result<()> {
let hook_path = hooks_dir.join("prepare-commit-msg");
if hook_path.exists() {
std::fs::remove_file(hook_path)?;
}
println!("{}", "Git hook removed successfully.".green());
Ok(())
}