182 lines
4.9 KiB
Markdown
182 lines
4.9 KiB
Markdown
|
# watcher
|
||
|
|
||
|
[![Build Status](https://travis-ci.org/radovskyb/watcher.svg?branch=master)](https://travis-ci.org/radovskyb/watcher)
|
||
|
|
||
|
`watcher` is a Go package for watching for files or directory changes (recursively or non recursively) without using filesystem events, which allows it to work cross platform consistently.
|
||
|
|
||
|
`watcher` watches for changes and notifies over channels either anytime an event or an error has occurred.
|
||
|
|
||
|
Events contain the `os.FileInfo` of the file or directory that the event is based on and the type of event and file or directory path.
|
||
|
|
||
|
[Installation](#installation)
|
||
|
[Features](#features)
|
||
|
[Example](#example)
|
||
|
[Contributing](#contributing)
|
||
|
[Watcher Command](#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
|
||
|
|
||
|
```shell
|
||
|
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.g `Name`, `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` or `Move` 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
|
||
|
|
||
|
```go
|
||
|
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:
|
||
|
```shell
|
||
|
watcher
|
||
|
```
|
||
|
(watches the current directory recursively for changes and notifies any events that occur.)
|
||
|
|
||
|
A more elaborate example using the `watcher` command:
|
||
|
```shell
|
||
|
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:
|
||
|
```python
|
||
|
import sys
|
||
|
|
||
|
for line in sys.stdin:
|
||
|
print (line + " - python")
|
||
|
```
|
||
|
|
||
|
Next, start watcher with the `pipe` and `cmd` flags enabled:
|
||
|
```shell
|
||
|
watcher -cmd="python script.py" -pipe=true
|
||
|
```
|
||
|
|
||
|
Now when changes are detected, the event's info will be output from the running python script.
|