package main import ( "log" "os" "path/filepath" "strings" "github.com/fsnotify/fsnotify" ) // shouldIgnore returns true for paths that should not trigger rebuilds func shouldIgnore(path string) bool { // Ignore build output and dependencies ignoreDirs := []string{"/dist/", "/node_modules/", "/.git/"} for _, dir := range ignoreDirs { if strings.Contains(path, dir) { return true } } // Also ignore if path ends with these directories for _, dir := range []string{"/dist", "/node_modules", "/.git"} { if strings.HasSuffix(path, dir) { return true } } return false } func watchFiles(dir string, changes chan<- FileChange) { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() // Add all directories recursively (except ignored ones) err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { if shouldIgnore(path) { return filepath.SkipDir } err = watcher.Add(path) if err != nil { log.Printf("Error watching %s: %v\n", path, err) } } return nil }) if err != nil { log.Fatal(err) } for { select { case event, ok := <-watcher.Events: if !ok { return } // Skip ignored paths if shouldIgnore(event.Name) { continue } // Handle different types of events var operation string switch { case event.Op&fsnotify.Write == fsnotify.Write: operation = "MODIFIED" case event.Op&fsnotify.Create == fsnotify.Create: operation = "CREATED" // If a new directory is created, start watching it if info, err := os.Stat(event.Name); err == nil && info.IsDir() { watcher.Add(event.Name) } case event.Op&fsnotify.Remove == fsnotify.Remove: operation = "REMOVED" case event.Op&fsnotify.Rename == fsnotify.Rename: operation = "RENAMED" case event.Op&fsnotify.Chmod == fsnotify.Chmod: operation = "CHMOD" default: operation = "UNKNOWN" } changes <- FileChange{ Path: event.Name, Operation: operation, } case err, ok := <-watcher.Errors: if !ok { return } log.Printf("Watcher error: %v\n", err) } } }