Skip to content

Instantly share code, notes, and snippets.

@ox
Last active December 23, 2018 20:54
Show Gist options
  • Save ox/df4484ab81753eeb51895e82c7f7ca88 to your computer and use it in GitHub Desktop.
Save ox/df4484ab81753eeb51895e82c7f7ca88 to your computer and use it in GitHub Desktop.
A fsnotify-powered watcher for Go that supports adding listeners
package main
import (
"log"
"github.com/fsnotify/fsnotify"
)
type CB func(Event)
type Event struct {
fsnotify.Event
}
func (e Event) IsCreate() bool {
return e.Op&fsnotify.Create == fsnotify.Create
}
func (e Event) IsWrite() bool {
return e.Op&fsnotify.Write == fsnotify.Write
}
func (e Event) IsRemove() bool {
return e.Op&fsnotify.Remove == fsnotify.Remove
}
func (e Event) IsRename() bool {
return e.Op&fsnotify.Rename == fsnotify.Rename
}
func (e Event) IsChmod() bool {
return e.Op&fsnotify.Chmod == fsnotify.Chmod
}
type Watcher struct {
*fsnotify.Watcher
done chan bool
listeners []CB
}
func NewWatcher() (*Watcher, error) {
watcher, err := fsnotify.NewWatcher()
return &Watcher{watcher, make(chan bool), make([]CB, 0)}, err
}
func (w *Watcher) AddListener(cb CB) {
w.listeners = append(w.listeners, cb)
}
// Start listening for file changes asynchronously
func (w *Watcher) Listen() {
w.done = make(chan bool)
go func() {
for {
select {
case event, ok := <-w.Events:
if !ok {
return
}
for _, cb := range w.listeners {
cb(Event{event})
}
case err, ok := <-w.Errors:
if !ok {
return
}
log.Println("error:", err)
case <-w.done:
return
}
}
}()
}
// Stop listening for changes
func (w *Watcher) Stop() {
w.done <- true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment