Преглед на файлове

watch: add a simple check when there are no exclusions (#1863)

Nick Santos преди 6 години
родител
ревизия
d744c97f13
променени са 2 файла, в които са добавени 69 реда и са изтрити 3 реда
  1. 25 2
      pkg/watch/notify_test.go
  2. 44 1
      pkg/watch/watcher_naive.go

+ 25 - 2
pkg/watch/notify_test.go

@@ -488,7 +488,7 @@ func TestWatchCountInnerFileWithIgnore(t *testing.T) {
 	assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
 }
 
-func TestIgnore(t *testing.T) {
+func TestIgnoreCreatedDir(t *testing.T) {
 	f := newNotifyFixture(t)
 	defer f.tearDown()
 
@@ -502,13 +502,36 @@ func TestIgnore(t *testing.T) {
 	f.WriteFile(file, "hello")
 	f.assertEvents(a)
 
-	expectedWatches := 3
+	expectedWatches := 2
 	if runtime.GOOS == "darwin" {
 		expectedWatches = 1
 	}
 	assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
 }
 
+func TestIgnoreInitialDir(t *testing.T) {
+	f := newNotifyFixture(t)
+	defer f.tearDown()
+
+	root := f.TempDir("root")
+	ignore, _ := dockerignore.NewDockerPatternMatcher(root, []string{"a/b"})
+	f.setIgnore(ignore)
+
+	a := f.JoinPath(root, "a")
+	b := f.JoinPath(a, "b")
+	file := f.JoinPath(b, "bigFile")
+	f.WriteFile(file, "hello")
+	f.watch(root)
+
+	f.assertEvents()
+
+	expectedWatches := 3
+	if runtime.GOOS == "darwin" {
+		expectedWatches = 2
+	}
+	assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
+}
+
 type notifyFixture struct {
 	out *bytes.Buffer
 	*tempdir.TempDirFixture

+ 44 - 1
pkg/watch/watcher_naive.go

@@ -78,6 +78,16 @@ func (d *naiveNotify) watchRecursively(dir string) error {
 		if !mode.IsDir() {
 			return nil
 		}
+
+		shouldSkipDir, err := d.shouldSkipDir(path)
+		if err != nil {
+			return err
+		}
+
+		if shouldSkipDir {
+			return filepath.SkipDir
+		}
+
 		err = d.add(path)
 		if err != nil {
 			if os.IsNotExist(err) {
@@ -145,7 +155,15 @@ func (d *naiveNotify) loop() {
 
 			shouldWatch := false
 			if mode.IsDir() {
-				// watch all directories
+				// watch directories unless we can skip them entirely
+				shouldSkipDir, err := d.shouldSkipDir(path)
+				if err != nil {
+					return err
+				}
+				if shouldSkipDir {
+					return filepath.SkipDir
+				}
+
 				shouldWatch = true
 			} else {
 				// watch files that are explicitly named, but don't watch others
@@ -188,6 +206,31 @@ func (d *naiveNotify) shouldNotify(path string) bool {
 	return false
 }
 
+func (d *naiveNotify) shouldSkipDir(path string) (bool, error) {
+	var err error
+	ignore := false
+
+	// If path is directly in the notifyList, we should always watch it.
+	if !d.notifyList[path] {
+		ignore, err = d.ignore.Matches(path)
+		if err != nil {
+			return false, errors.Wrapf(err, "Error matching %s: %v", path, err)
+		}
+	}
+
+	// The ignore filter is telling us to ignore this file,
+	// but we may have to watch it anyway to catch files underneath it.
+	if ignore {
+		if !d.ignore.Exclusions() {
+			return true, nil
+		}
+
+		// TODO(nick): Add more complex logic for interpreting exclusion patterns.
+	}
+
+	return false, nil
+}
+
 func (d *naiveNotify) add(path string) error {
 	err := d.watcher.Add(path)
 	if err != nil {