Commits
Diff
package watcher
import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/fsnotify/fsnotify"
)
// !MAN: Test
func New(dir string, handler func(string, string)) {
// Create a new watcher
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
// Add directories recursively
err = addWatchRecursive(watcher, dir)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Watching directory and subdirectories: %s\n", dir)
// Channel to signal exit
done := make(chan bool)
cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
// Start watching for events
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
path := filepath.Join(cwd, event.Name)
if (event.Op&fsnotify.Create == fsnotify.Create ||
event.Op&fsnotify.Rename == fsnotify.Rename ||
event.Op&fsnotify.Write == fsnotify.Write) && HasNoHiddenPath(path) {
handler(fmt.Sprint(event.Op), path)
}
// If a new directory is created, add it to the watcher
if event.Op&fsnotify.Create == fsnotify.Create {
info, err := os.Stat(event.Name)
if err == nil && info.IsDir() {
err := addWatchRecursive(watcher, event.Name)
if err != nil {
log.Printf("Failed to watch new directory: %s\n", err)
}
}
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
fmt.Printf("Error: %s\n", err)
}
}
}()
// Wait for the watcher to finish
<-done
}
// addWatchRecursive adds a directory and all its subdirectories to the watcher
func addWatchRecursive(watcher *fsnotify.Watcher, dir string) error {
return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
err := watcher.Add(path)
if err != nil {
log.Printf("Error adding directory to watcher: %s\n", err)
return err
}
}
return nil
})
}
func HasNoHiddenPath(path string) bool {
components := strings.Split(filepath.Clean(path), string(filepath.Separator))
for _, component := range components {
if strings.HasPrefix(component, ".") {
return false
}
}
return true
}
// !remove comments