129 lines
4.2 KiB
Python
129 lines
4.2 KiB
Python
"""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()]
|