@@ -21,7 +21,11 @@ type naiveNotify struct {
21
21
events chan fsnotify.Event
22
22
wrappedEvents chan FileEvent
23
23
errors chan error
24
- watchList map [string ]bool
24
+
25
+ // Paths that we're watching that should be passed up to the caller.
26
+ // Note that we may have to watch ancestors of these paths
27
+ // in order to fulfill the API promise.
28
+ notifyList map [string ]bool
25
29
}
26
30
27
31
func (d * naiveNotify ) Add (name string ) error {
@@ -32,24 +36,22 @@ func (d *naiveNotify) Add(name string) error {
32
36
33
37
// if it's a file that doesn't exist, watch its parent
34
38
if os .IsNotExist (err ) {
35
- err , fileWatched : = d .watchUpRecursively (name )
39
+ err = d .watchAncestorOfMissingPath (name )
36
40
if err != nil {
37
- return errors .Wrapf (err , "watchUpRecursively (%q)" , name )
41
+ return errors .Wrapf (err , "watchAncestorOfMissingPath (%q)" , name )
38
42
}
39
- d .watchList [fileWatched ] = true
40
43
} else if fi .IsDir () {
41
44
err = d .watchRecursively (name )
42
45
if err != nil {
43
46
return errors .Wrapf (err , "notify.Add(%q)" , name )
44
47
}
45
- d .watchList [name ] = true
46
48
} else {
47
49
err = d .watcher .Add (name )
48
50
if err != nil {
49
51
return errors .Wrapf (err , "notify.Add(%q)" , name )
50
52
}
51
- d .watchList [name ] = true
52
53
}
54
+ d .notifyList [name ] = true
53
55
54
56
return nil
55
57
}
@@ -71,22 +73,22 @@ func (d *naiveNotify) watchRecursively(dir string) error {
71
73
})
72
74
}
73
75
74
- func (d * naiveNotify ) watchUpRecursively (path string ) ( error , string ) {
76
+ func (d * naiveNotify ) watchAncestorOfMissingPath (path string ) error {
75
77
if path == string (filepath .Separator ) {
76
- return fmt .Errorf ("cannot watch root directory" ), ""
78
+ return fmt .Errorf ("cannot watch root directory" )
77
79
}
78
80
79
81
_ , err := os .Stat (path )
80
82
if err != nil && ! os .IsNotExist (err ) {
81
- return errors .Wrapf (err , "os.Stat(%q)" , path ), ""
83
+ return errors .Wrapf (err , "os.Stat(%q)" , path )
82
84
}
83
85
84
86
if os .IsNotExist (err ) {
85
87
parent := filepath .Dir (path )
86
- return d .watchUpRecursively (parent )
88
+ return d .watchAncestorOfMissingPath (parent )
87
89
}
88
90
89
- return d .watcher .Add (path ), path
91
+ return d .watcher .Add (path )
90
92
}
91
93
92
94
func (d * naiveNotify ) Close () error {
@@ -122,35 +124,39 @@ func (d *naiveNotify) loop() {
122
124
Op : fsnotify .Create ,
123
125
Name : path ,
124
126
}
125
- d .sendEventIfWatched (newE )
126
- // TODO(dmiller): symlinks 😭
127
- err = d .Add (path )
128
- if err != nil {
129
- log .Printf ("Error watching path %s: %s" , e .Name , err )
127
+
128
+ if d .shouldNotify (newE ) {
129
+ d .wrappedEvents <- FileEvent {newE .Name }
130
+
131
+ // TODO(dmiller): symlinks 😭
132
+ err = d .Add (path )
133
+ if err != nil {
134
+ log .Printf ("Error watching path %s: %s" , e .Name , err )
135
+ }
130
136
}
131
137
return nil
132
138
})
133
139
if err != nil {
134
140
log .Printf ("Error walking directory %s: %s" , e .Name , err )
135
141
}
136
- } else {
137
- d .sendEventIfWatched ( e )
142
+ } else if d . shouldNotify ( e ) {
143
+ d .wrappedEvents <- FileEvent { e . Name }
138
144
}
139
145
}
140
146
}
141
147
142
- func (d * naiveNotify ) sendEventIfWatched (e fsnotify.Event ) {
143
- if _ , ok := d .watchList [e .Name ]; ok {
144
- d . wrappedEvents <- FileEvent { e . Name }
148
+ func (d * naiveNotify ) shouldNotify (e fsnotify.Event ) bool {
149
+ if _ , ok := d .notifyList [e .Name ]; ok {
150
+ return true
145
151
} else {
146
152
// TODO(dmiller): maybe use a prefix tree here?
147
- for path := range d .watchList {
153
+ for path := range d .notifyList {
148
154
if pathIsChildOf (e .Name , path ) {
149
- d .wrappedEvents <- FileEvent {e .Name }
150
- break
155
+ return true
151
156
}
152
157
}
153
158
}
159
+ return false
154
160
}
155
161
156
162
func NewWatcher () (* naiveNotify , error ) {
@@ -166,7 +172,7 @@ func NewWatcher() (*naiveNotify, error) {
166
172
events : fsw .Events ,
167
173
wrappedEvents : wrappedEvents ,
168
174
errors : fsw .Errors ,
169
- watchList : map [string ]bool {},
175
+ notifyList : map [string ]bool {},
170
176
}
171
177
172
178
go wmw .loop ()
0 commit comments