Files
ss/internal/hook/manager.go
2026-07-19 20:01:38 +08:00

149 lines
3.6 KiB
Go

// Package hook manages hook scripts for scientific-surfing.
package hook
import (
"fmt"
"os"
"path/filepath"
"strings"
"gitea.epss.net.cn/klesh/ss/internal/editor"
"gitea.epss.net.cn/klesh/ss/internal/storage"
"gitea.epss.net.cn/klesh/ss/templates"
)
// Manager manages hook scripts for scientific-surfing.
type Manager struct {
Storage *storage.Manager
HooksDir string
}
// New creates a hook Manager rooted at the storage manager's config directory.
func New(s *storage.Manager) *Manager {
return &Manager{
Storage: s,
HooksDir: filepath.Join(s.ConfigDir, "hooks"),
}
}
// Init initializes the hooks directory by copying the embedded template hooks.
func (m *Manager) Init() {
entries, err := templates.Hooks.ReadDir("hooks")
if err != nil {
fmt.Printf("Template hooks directory not found: %v\n", err)
return
}
if err := os.MkdirAll(m.HooksDir, 0o755); err != nil {
fmt.Printf("Failed to create hooks directory: %v\n", err)
return
}
copiedCount := 0
for _, entry := range entries {
if entry.IsDir() {
continue
}
destFile := filepath.Join(m.HooksDir, entry.Name())
if _, err := os.Stat(destFile); err == nil {
fmt.Printf("Skipped (already exists): %s\n", entry.Name())
continue
}
content, err := templates.Hooks.ReadFile("hooks/" + entry.Name())
if err != nil {
fmt.Printf("Failed to read template %s: %v\n", entry.Name(), err)
continue
}
if err := os.WriteFile(destFile, content, 0o644); err != nil {
fmt.Printf("Failed to copy %s: %v\n", entry.Name(), err)
continue
}
copiedCount++
fmt.Printf("Copied: %s\n", entry.Name())
}
fmt.Printf("\nInitialized hooks directory with %d new scripts.\n", copiedCount)
fmt.Printf("Location: %s\n", m.HooksDir)
}
// ListHooks displays the hooks directory location and lists all hook scripts.
func (m *Manager) ListHooks() {
fmt.Printf("Hooks directory: %s\n", m.HooksDir)
if _, err := os.Stat(m.HooksDir); os.IsNotExist(err) {
fmt.Println("Hooks directory does not exist. Run 'init' to create it.")
return
}
hookFiles := m.getHookFiles()
if len(hookFiles) == 0 {
fmt.Println("No hook scripts found.")
return
}
fmt.Printf("\nFound %d hook script(s):\n", len(hookFiles))
for _, f := range hookFiles {
fmt.Printf(" - %s\n", f)
}
}
// Edit opens a hook script with the system default editor.
func (m *Manager) Edit(scriptName string) {
if _, err := os.Stat(m.HooksDir); os.IsNotExist(err) {
fmt.Println("Hooks directory does not exist. Run 'init' to create it.")
return
}
scriptPath := filepath.Join(m.HooksDir, scriptName)
if _, err := os.Stat(scriptPath); os.IsNotExist(err) {
m.printNotFound(scriptName)
return
}
editor.OpenFileInEditor(scriptPath)
}
// Rm removes a hook script.
func (m *Manager) Rm(scriptName string) {
if _, err := os.Stat(m.HooksDir); os.IsNotExist(err) {
fmt.Println("Hooks directory does not exist.")
return
}
scriptPath := filepath.Join(m.HooksDir, scriptName)
if _, err := os.Stat(scriptPath); os.IsNotExist(err) {
m.printNotFound(scriptName)
return
}
if err := os.Remove(scriptPath); err != nil {
fmt.Printf("Failed to remove script: %v\n", err)
return
}
fmt.Printf("Removed: %s\n", scriptName)
}
func (m *Manager) printNotFound(scriptName string) {
fmt.Printf("Script '%s' not found.\n", scriptName)
available := m.getHookFiles()
if len(available) > 0 {
fmt.Printf("Available scripts: %s\n", strings.Join(available, ", "))
}
}
func (m *Manager) getHookFiles() []string {
entries, err := os.ReadDir(m.HooksDir)
if err != nil {
return nil
}
var files []string
for _, entry := range entries {
if !entry.IsDir() {
files = append(files, entry.Name())
}
}
return files
}