package watcher import ( "github.com/fsnotify/fsnotify" ) // File is a file watcher that notifies when a file has been changed type File struct { watcher *fsnotify.Watcher shutdown chan struct{} } // NewFile is a standard constructor func NewFile() (*File, error) { watcher, err := fsnotify.NewWatcher() if err != nil { return nil, err } f := &File{ watcher: watcher, shutdown: make(chan struct{}), } return f, nil } // Add adds a file to start watching func (f *File) Add(filepath string) error { return f.watcher.Add(filepath) } // Shutdown stop the file watching run loop func (f *File) Shutdown() { // don't block if Start quit early select { case f.shutdown <- struct{}{}: default: } } // Start is a runloop to watch for files changes from the file paths added from Add() func (f *File) Start(notifier Notification) { for { select { case event, ok := <-f.watcher.Events: if !ok { return } if event.Op&fsnotify.Write == fsnotify.Write { notifier.WatcherItemDidChange(event.Name) } case err, ok := <-f.watcher.Errors: if !ok { return } notifier.WatcherDidError(err) case <-f.shutdown: f.watcher.Close() return } } }