-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwatcher.go
108 lines (92 loc) · 1.98 KB
/
watcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package packer
import (
"fmt"
"github.com/radovskyb/watcher"
"log"
"regexp"
"time"
)
type Watcher struct {
options WatcherOptions
w *watcher.Watcher
hooks map[string]func(path string) error
}
type WatcherOptions struct {
Patterns []string `json:"patterns"`
Includes []string `json:"includes"`
Excludes []string `json:"excludes"`
}
func NewWatcher(options WatcherOptions) *Watcher {
w := watcher.New()
w.SetMaxEvents(1)
w.FilterOps(watcher.Write)
return &Watcher{
options: options,
w: w,
hooks: make(map[string]func(string) error),
}
}
func (fw *Watcher) Start() error {
go fw.watch()
for _, p := range fw.options.Patterns {
r, err := regexp.Compile(p)
if err != nil {
return err
}
fw.w.AddFilterHook(watcher.RegexFilterHook(r, true))
}
for _, exc := range fw.options.Excludes {
if err := fw.w.Ignore(exc); err != nil {
return err
}
}
if len(fw.options.Includes) > 0 {
for _, inc := range fw.options.Includes {
if err := fw.w.AddRecursive(inc); err != nil {
return err
}
}
} else {
if err := fw.w.AddRecursive("."); err != nil {
return err
}
}
for p, f := range fw.w.WatchedFiles() {
fmt.Printf("%s: %s\n", p, f.Name())
}
return fw.w.Start(time.Millisecond * 500)
}
func (fw *Watcher) AddHook(name string, f func(path string) error) {
fw.hooks[name] = f
}
func (fw *Watcher) Close() {
fw.w.Close()
}
func (fw *Watcher) Closed() <-chan struct{} {
return fw.w.Closed
}
func (fw *Watcher) watch() {
lastWrite := map[string]time.Time{}
for {
select {
case e := <-fw.w.Event:
t := time.Now()
lw, ok := lastWrite[e.Path]
if ok && lw.Add(time.Millisecond*500).After(t) {
log.Printf("%s: cooldown\n", e.Path)
break
}
lastWrite[e.Path] = t
log.Printf("%+v\n", e)
for name, f := range fw.hooks {
if err := f(e.Path); err != nil {
log.Printf("%s: %s\n", name, err)
}
}
case err := <-fw.w.Error:
fmt.Printf("filewatcher: %s\n", err)
case <-fw.w.Closed:
return
}
}
}