package main import ( "flag" "fmt" "log" "os" "os/signal" "path/filepath" "syscall" "time" "Moonshark/modules/http" "Moonshark/state" ) var ( watchFlag = flag.Bool("watch", false, "Watch script files for changes and restart") wFlag = flag.Bool("w", false, "Watch script files for changes and restart (short)") ) func main() { flag.Parse() if flag.NArg() < 1 { fmt.Fprintf(os.Stderr, "Usage: %s [--watch|-w] \n", filepath.Base(os.Args[0])) os.Exit(1) } scriptPath := flag.Arg(0) watchMode := *watchFlag || *wFlag if watchMode { runWithWatcher(scriptPath) } else { runOnce(scriptPath) } } func runOnce(scriptPath string) { luaState, err := state.NewFromScript(scriptPath) if err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } defer luaState.Close() if err := luaState.ExecuteFile(scriptPath); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } if http.HasActiveServers() { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) fmt.Println("HTTP servers running. Press Ctrl+C to exit.") go func() { <-sigChan fmt.Println("\nShutting down...") os.Exit(0) }() http.WaitForServers() } } func runWithWatcher(scriptPath string) { watcher, err := NewFileWatcher(500) // 500ms debounce if err != nil { fmt.Fprintf(os.Stderr, "Failed to create file watcher: %v\n", err) os.Exit(1) } defer watcher.Close() if err := watcher.DiscoverRequiredFiles(scriptPath); err != nil { fmt.Fprintf(os.Stderr, "Failed to watch files: %v\n", err) os.Exit(1) } restartCh := watcher.Start() sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) fmt.Printf("Starting %s in watch mode...\n", scriptPath) for { // Clear cache before each run state.ClearCache() // Create and run state luaState, err := state.NewFromScript(scriptPath) if err != nil { log.Printf("Error creating state: %v", err) time.Sleep(1 * time.Second) continue } if err := luaState.ExecuteFile(scriptPath); err != nil { log.Printf("Execution error: %v", err) luaState.Close() time.Sleep(1 * time.Second) continue } // If not a long-running process, wait for changes and restart if !http.HasActiveServers() { fmt.Println("Script completed. Waiting for changes...") luaState.Close() select { case <-restartCh: fmt.Println("Files changed, restarting...") continue case <-sigChan: fmt.Println("\nExiting...") return } } // Long-running process - wait for restart signal or exit signal fmt.Println("HTTP servers running. Watching for file changes...") select { case <-restartCh: fmt.Println("Files changed, restarting...") http.StopAllServers() luaState.Close() time.Sleep(100 * time.Millisecond) // Brief pause for cleanup continue case <-sigChan: fmt.Println("\nShutting down...") http.StopAllServers() luaState.Close() return } } }