diff --git a/watcher.go b/watcher.go index f459195..5c76a34 100644 --- a/watcher.go +++ b/watcher.go @@ -2,6 +2,8 @@ package main import ( "github.com/howeyc/fsnotify" + "os" + "path/filepath" ) func StartWatching(watchDir string, fileUpdates chan *Event) { @@ -10,39 +12,58 @@ func StartWatching(watchDir string, fileUpdates chan *Event) { panic("Failed to create fsnotify watcher") } - err = watcher.Watch(watchDir) - if err != nil { - panic("Failed to watch " + watchDir) + //function called by filepath.Walk to start watching a directory and all subdirectories + watchDirFn := func(path string, info os.FileInfo, err error) error { + if info.IsDir() { + err = watcher.Watch(path) + if err != nil { + panic("Failed to watch " + path) + } + } + return nil } - for { - select { - case ev := <-watcher.Event: - event := new(Event) - if ev.IsCreate() || ev.IsModify() { - event.Type = UPDATE - } else if ev.IsDelete() || ev.IsRename() { - event.Type = DELETE - } else { - panic("Unknown fsnotify event type") - } - - event.Path = ev.Name - if event.IsUpdate() { - event.Hash, err = HashFile(ev.Name) - if err != nil { + //processes all the fsnotify events into asink events + go func() { + for { + select { + case ev := <-watcher.Event: + //if a directory was created, begin recursively watching all its subdirectories + if fi, err := os.Stat(ev.Name); err == nil && fi.IsDir() { + if ev.IsCreate() { + filepath.Walk(ev.Name, watchDirFn) + } continue } - } else { - event.Hash = "" + + event := new(Event) + if ev.IsCreate() || ev.IsModify() { + event.Type = UPDATE + } else if ev.IsDelete() || ev.IsRename() { + event.Type = DELETE + } else { + panic("Unknown fsnotify event type") + } + + event.Path = ev.Name + if event.IsUpdate() { + event.Hash, err = HashFile(ev.Name) + if err != nil { + panic("file deleted already?") + continue + } + } else { + event.Hash = "" + } + + fileUpdates <- event + + case err := <-watcher.Error: + panic(err) } - - fileUpdates <- event - - //TODO if creating a directory, start watching it (and then initiate a full scan of it so we're sure nothing slipped through the cracks) - - case err := <-watcher.Error: - panic(err) } - } + }() + + //start watching the directory passed in + filepath.Walk(watchDir, watchDirFn) }