Jay Taylor's notes
back to listing indexradovskyb/watcher: watcher is a Go package for watching for files or directory changes without using filesystem events.
[web search]Latest commit
README.md
watcher
Features
Example
Contributing
Watcher Command
Update
- Event.OldPath has been added [Aug 17, 2019]
- Added new file filter hooks (Including a built in regexp filtering hook) [Dec 12, 2018]
- Event.Path for Rename and Move events is now returned in the format of
fromPath -> toPath
Chmod event is not supported under windows.
Installation
go get -u github.com/radovskyb/watcher/...
Features
- Customizable polling interval.
- Filter Events.
- Watch folders recursively or non-recursively.
- Choose to ignore hidden files.
- Choose to ignore specified files and folders.
- Notifies the
os.FileInfo
of the file that the event is based on. e.gName
,ModTime
,IsDir
, etc. - Notifies the full path of the file that the event is based on or the old and new paths if the event was a
Rename
orMove
event. - Limit amount of events that can be received per watching cycle.
- List the files being watched.
- Trigger custom events.
Todo
- Write more tests.
- Write benchmarks.
Example
package main import ( "fmt" "log" "time" "github.com/radovskyb/watcher" ) func main() { w := watcher.New() // SetMaxEvents to 1 to allow at most 1 event's to be received // on the Event channel per watching cycle. // // If SetMaxEvents is not set, the default is to send all events. w.SetMaxEvents(1) // Only notify rename and move events. w.FilterOps(watcher.Rename, watcher.Move) // Only files that match the regular expression during file listings // will be watched. r := regexp.MustCompile("^abc$") w.AddFilterHook(watcher.RegexFilterHook(r, false)) go func() { for { select { case event := <-w.Event: fmt.Println(event) // Print the event's info. case err := <-w.Error: log.Fatalln(err) case <-w.Closed: return } } }() // Watch this folder for changes. if err := w.Add("."); err != nil { log.Fatalln(err) } // Watch test_folder recursively for changes. if err := w.AddRecursive("../test_folder"); err != nil { log.Fatalln(err) } // Print a list of all of the files and folders currently // being watched and their paths. for path, f := range w.WatchedFiles() { fmt.Printf("%s: %s\n", path, f.Name()) } fmt.Println() // Trigger 2 events after watcher started. go func() { w.Wait() w.TriggerEvent(watcher.Create, nil) w.TriggerEvent(watcher.Remove, nil) }() // Start the watching process - it'll check for changes every 100ms. if err := w.Start(time.Millisecond * 100); err != nil { log.Fatalln(err) } }
Contributing
If you would ike to contribute, simply submit a pull request.
Command
watcher
comes with a simple command which is installed when using the go get
command from above.
Usage
Usage of watcher:
-cmd string
command to run when an event occurs
-dotfiles
watch dot files (default true)
-ignore string
comma separated list of paths to ignore
-interval string
watcher poll interval (default "100ms")
-keepalive
keep alive when a cmd returns code != 0
-list
list watched files on start
-pipe
pipe event's info to command's stdin
-recursive
watch folders recursively (default true)
-startcmd
run the command when watcher starts
All of the flags are optional and watcher can also be called by itself:
watcher
(watches the current directory recursively for changes and notifies any events that occur.)
A more elaborate example using the watcher
command:
watcher -dotfiles=false -recursive=false -cmd="./myscript" main.go ../
In this example, watcher
will ignore dot files and folders and won't watch any of the specified folders recursively. It will also run the script ./myscript
anytime an event occurs while watching main.go
or any files or folders in the previous directory (../
).
Using the pipe
and cmd
flags together will send the event's info to the command's stdin when changes are detected.
First create a file called script.py
with the following contents:
import sys for line in sys.stdin: print (line + " - python")
Next, start watcher with the pipe
and cmd
flags enabled:
watcher -cmd="python script.py" -pipe=true
Now when changes are detected, the event's info will be output from the running python script.