import os import stat from pathlib import Path from typing import Optional import click from local_commit_message_generator.config import Config from local_commit_message_generator.templates import TemplateManager class HookManager: def __init__(self, repo_path: Optional[str] = None): self.repo_path = Path(repo_path) if repo_path else Path.cwd() self.hooks_dir = self.repo_path / ".git" / "hooks" self.hook_file = self.hooks_dir / "prepare-commit-msg" def check_git_repo(self) -> bool: git_dir = self.repo_path / ".git" return git_dir.exists() and git_dir.is_dir() def install_hook(self, config: Config) -> bool: if not self.check_git_repo(): click.echo("Error: Not a git repository", err=True) return False self.hooks_dir.mkdir(parents=True, exist_ok=True) existing_content = None if self.hook_file.exists(): existing_content = self.hook_file.read_text() click.echo(f"Backing up existing hook to {self.hook_file}.backup") backup_file = self.hook_file.with_suffix(".backup") backup_file.write_text(existing_content) hook_content = self._generate_hook_script(config) self.hook_file.write_text(hook_content) os.chmod(self.hook_file, stat.S_IRWXU) click.echo(f"Hook installed at {self.hook_file}") return True def uninstall_hook(self) -> bool: if not self.check_git_repo(): click.echo("Error: Not a git repository", err=True) return False if not self.hook_file.exists(): click.echo("Hook not installed") return False backup_file = self.hook_file.with_suffix(".backup") if backup_file.exists(): backup_file.replace(self.hook_file) click.echo("Restored backup hook") else: self.hook_file.unlink() click.echo("Removed hook") return True def _generate_hook_script(self, config: Config) -> str: template_manager = TemplateManager() template = template_manager.get_template("hook") return template.format( script_path=os.path.abspath(__file__), module_name="local_commit_message_generator" )