Skip to content

Commit d744c97

Browse files
nicksndeloof
authored andcommitted
watch: add a simple check when there are no exclusions (docker#1863)
1 parent 37647bc commit d744c97

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

pkg/watch/notify_test.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ func TestWatchCountInnerFileWithIgnore(t *testing.T) {
488488
assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
489489
}
490490

491-
func TestIgnore(t *testing.T) {
491+
func TestIgnoreCreatedDir(t *testing.T) {
492492
f := newNotifyFixture(t)
493493
defer f.tearDown()
494494

@@ -502,13 +502,36 @@ func TestIgnore(t *testing.T) {
502502
f.WriteFile(file, "hello")
503503
f.assertEvents(a)
504504

505-
expectedWatches := 3
505+
expectedWatches := 2
506506
if runtime.GOOS == "darwin" {
507507
expectedWatches = 1
508508
}
509509
assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
510510
}
511511

512+
func TestIgnoreInitialDir(t *testing.T) {
513+
f := newNotifyFixture(t)
514+
defer f.tearDown()
515+
516+
root := f.TempDir("root")
517+
ignore, _ := dockerignore.NewDockerPatternMatcher(root, []string{"a/b"})
518+
f.setIgnore(ignore)
519+
520+
a := f.JoinPath(root, "a")
521+
b := f.JoinPath(a, "b")
522+
file := f.JoinPath(b, "bigFile")
523+
f.WriteFile(file, "hello")
524+
f.watch(root)
525+
526+
f.assertEvents()
527+
528+
expectedWatches := 3
529+
if runtime.GOOS == "darwin" {
530+
expectedWatches = 2
531+
}
532+
assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
533+
}
534+
512535
type notifyFixture struct {
513536
out *bytes.Buffer
514537
*tempdir.TempDirFixture

pkg/watch/watcher_naive.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ func (d *naiveNotify) watchRecursively(dir string) error {
7878
if !mode.IsDir() {
7979
return nil
8080
}
81+
82+
shouldSkipDir, err := d.shouldSkipDir(path)
83+
if err != nil {
84+
return err
85+
}
86+
87+
if shouldSkipDir {
88+
return filepath.SkipDir
89+
}
90+
8191
err = d.add(path)
8292
if err != nil {
8393
if os.IsNotExist(err) {
@@ -145,7 +155,15 @@ func (d *naiveNotify) loop() {
145155

146156
shouldWatch := false
147157
if mode.IsDir() {
148-
// watch all directories
158+
// watch directories unless we can skip them entirely
159+
shouldSkipDir, err := d.shouldSkipDir(path)
160+
if err != nil {
161+
return err
162+
}
163+
if shouldSkipDir {
164+
return filepath.SkipDir
165+
}
166+
149167
shouldWatch = true
150168
} else {
151169
// watch files that are explicitly named, but don't watch others
@@ -188,6 +206,31 @@ func (d *naiveNotify) shouldNotify(path string) bool {
188206
return false
189207
}
190208

209+
func (d *naiveNotify) shouldSkipDir(path string) (bool, error) {
210+
var err error
211+
ignore := false
212+
213+
// If path is directly in the notifyList, we should always watch it.
214+
if !d.notifyList[path] {
215+
ignore, err = d.ignore.Matches(path)
216+
if err != nil {
217+
return false, errors.Wrapf(err, "Error matching %s: %v", path, err)
218+
}
219+
}
220+
221+
// The ignore filter is telling us to ignore this file,
222+
// but we may have to watch it anyway to catch files underneath it.
223+
if ignore {
224+
if !d.ignore.Exclusions() {
225+
return true, nil
226+
}
227+
228+
// TODO(nick): Add more complex logic for interpreting exclusion patterns.
229+
}
230+
231+
return false, nil
232+
}
233+
191234
func (d *naiveNotify) add(path string) error {
192235
err := d.watcher.Add(path)
193236
if err != nil {

0 commit comments

Comments
 (0)