"""Hook manager for scientific-surfing application.""" import os import shutil import subprocess from pathlib import Path from typing import List from scientific_surfing.storage import StorageManager class HookManager: """Manages hook scripts for scientific-surfing.""" def __init__(self, storage: StorageManager) -> None: """Initialize hook manager. Args: config_dir: Optional configuration directory path. If not provided, uses default user config directory. """ self.storage = storage self.config_dir = storage.config_dir self.hooks_dir = self.config_dir / "hooks" self.template_hooks_dir = Path(__file__).parent / "templates" / "hooks" def init(self) -> None: """Initialize hooks directory by copying template hooks.""" if not self.template_hooks_dir.exists(): print(f"Template hooks directory not found: {self.template_hooks_dir}") return self.hooks_dir.mkdir(parents=True, exist_ok=True) copied_count = 0 for hook_file in self.template_hooks_dir.iterdir(): if hook_file.is_file(): dest_file = self.hooks_dir / hook_file.name if not dest_file.exists(): shutil.copy2(hook_file, dest_file) copied_count += 1 print(f"Copied: {hook_file.name}") else: print(f"Skipped (already exists): {hook_file.name}") print(f"\nInitialized hooks directory with {copied_count} new scripts.") print(f"Location: {self.hooks_dir}") def list(self) -> None: """Display hooks directory location and list all hook scripts.""" print(f"Hooks directory: {self.hooks_dir}") if not self.hooks_dir.exists(): print("Hooks directory does not exist. Run 'init' to create it.") return hook_files = self._get_hook_files() if not hook_files: print("No hook scripts found.") else: print(f"\nFound {len(hook_files)} hook script(s):") for hook_file in hook_files: print(f" - {hook_file}") def edit(self, script_name: str) -> None: """Open a hook script with system default editor. Args: script_name: Name of the hook script to edit. """ if not self.hooks_dir.exists(): print("Hooks directory does not exist. Run 'init' to create it.") return script_path = self.hooks_dir / script_name if not script_path.exists(): available = self._get_hook_files() print(f"Script '{script_name}' not found.") if available: print(f"Available scripts: {', '.join(available)}") return editor = os.environ.get('EDITOR', 'notepad' if os.name == 'nt' else 'nano') try: subprocess.run([editor, str(script_path)], check=True) except subprocess.CalledProcessError as e: print(f"Failed to open editor: {e}") except FileNotFoundError: print(f"Editor '{editor}' not found. Please set EDITOR environment variable.") def rm(self, script_name: str) -> None: """Remove a hook script. Args: script_name: Name of the hook script to remove. """ if not self.hooks_dir.exists(): print("Hooks directory does not exist.") return script_path = self.hooks_dir / script_name if not script_path.exists(): available = self._get_hook_files() print(f"Script '{script_name}' not found.") if available: print(f"Available scripts: {', '.join(available)}") return try: script_path.unlink() print(f"Removed: {script_name}") except OSError as e: print(f"Failed to remove script: {e}") def _get_hook_files(self) -> List[str]: """Get list of hook script files. Returns: List of hook script filenames. """ if not self.hooks_dir.exists(): return [] return [f.name for f in self.hooks_dir.iterdir() if f.is_file()]