Skip to content

Commit 9453c6c

Browse files
fix: handle recursive watcher ignore paths correctly
Signed-off-by: ManManavadaria <manmanavadaria@gmail.com>
1 parent b8effba commit 9453c6c

5 files changed

Lines changed: 45 additions & 9 deletions

File tree

pkg/compose/watch.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,9 @@ func (s *composeService) watch(ctx context.Context, project *types.Project, opti
198198
eg, ctx := errgroup.WithContext(ctx)
199199

200200
var (
201-
rules []watchRule
202-
paths []string
201+
rules []watchRule
202+
paths []string
203+
ignoreMatchers []watch.PathMatcher
203204
)
204205
for serviceName, service := range project.Services {
205206
config, err := loadDevelopmentConfig(service, project)
@@ -254,6 +255,11 @@ func (s *composeService) watch(ctx context.Context, project *types.Project, opti
254255
}
255256
}
256257
}
258+
ignore, err := watch.NewDockerPatternMatcher(trigger.Path, trigger.Ignore)
259+
if err != nil {
260+
return nil, err
261+
}
262+
ignoreMatchers = append(ignoreMatchers, ignore)
257263
paths = append(paths, trigger.Path)
258264
}
259265

@@ -268,7 +274,7 @@ func (s *composeService) watch(ctx context.Context, project *types.Project, opti
268274
return nil, fmt.Errorf("none of the selected services is configured for watch, consider setting a 'develop' section")
269275
}
270276

271-
watcher, err := watch.NewWatcher(paths)
277+
watcher, err := watch.NewWatcher(paths, watch.NewCompositeMatcher(ignoreMatchers...))
272278
if err != nil {
273279
return nil, err
274280
}

pkg/watch/notify.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ func (EmptyMatcher) MatchesEntireDir(f string) (bool, error) { return false, nil
8080

8181
var _ PathMatcher = EmptyMatcher{}
8282

83-
func NewWatcher(paths []string) (Notify, error) {
84-
return newWatcher(paths)
83+
func NewWatcher(paths []string, ignore PathMatcher) (Notify, error) {
84+
return newWatcher(paths, ignore)
8585
}
8686

8787
const WindowsBufferSizeEnvVar = "COMPOSE_WATCH_WINDOWS_BUFFER_SIZE"

pkg/watch/notify_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ func (f *notifyFixture) rebuildWatcher() {
526526
}
527527

528528
// create a new watcher
529-
notify, err := NewWatcher(f.paths)
529+
notify, err := NewWatcher(f.paths, EmptyMatcher{})
530530
if err != nil {
531531
f.T().Fatal(err)
532532
}

pkg/watch/watcher_darwin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (d *fseventNotify) Errors() chan error {
115115
return d.errors
116116
}
117117

118-
func newWatcher(paths []string) (Notify, error) {
118+
func newWatcher(paths []string, _ PathMatcher) (Notify, error) {
119119
dw := &fseventNotify{
120120
stream: &fsevents.EventStream{
121121
Latency: 50 * time.Millisecond,

pkg/watch/watcher_naive.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type naiveNotify struct {
4545
// the notify list. It might be better to store this in a tree
4646
// structure, so we can filter the list quickly.
4747
notifyList map[string]bool
48+
ignore PathMatcher
4849

4950
isWatcherRecursive bool
5051
watcher *fsnotify.Watcher
@@ -113,6 +114,10 @@ func (d *naiveNotify) watchRecursively(dir string) error {
113114

114115
return filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
115116
if err != nil {
117+
if os.IsPermission(err) && d.shouldIgnore(path) {
118+
logrus.Debugf("Ignoring path: %s", path)
119+
return nil
120+
}
116121
return err
117122
}
118123

@@ -240,6 +245,11 @@ func (d *naiveNotify) shouldSkipDir(path string) bool {
240245
return false
241246
}
242247

248+
// If path is present in the ignore list then we should ignore it
249+
if d.shouldIgnore(path) {
250+
return true
251+
}
252+
243253
// Suppose we're watching
244254
// /src/.tiltignore
245255
// but the .tiltignore file doesn't exist.
@@ -260,6 +270,26 @@ func (d *naiveNotify) shouldSkipDir(path string) bool {
260270
return true
261271
}
262272

273+
func (d *naiveNotify) shouldIgnore(path string) bool {
274+
if d.ignore == nil {
275+
return false
276+
}
277+
matches, err := d.ignore.MatchesEntireDir(path)
278+
if err != nil {
279+
logrus.Debugf("error checking ignored directory %q: %v", path, err)
280+
return false
281+
}
282+
if matches {
283+
return true
284+
}
285+
matches, err = d.ignore.Matches(path)
286+
if err != nil {
287+
logrus.Debugf("error checking ignored path %q: %v", path, err)
288+
return false
289+
}
290+
return matches
291+
}
292+
263293
func (d *naiveNotify) add(path string) error {
264294
err := d.watcher.Add(path)
265295
if err != nil {
@@ -270,7 +300,7 @@ func (d *naiveNotify) add(path string) error {
270300
return nil
271301
}
272302

273-
func newWatcher(paths []string) (Notify, error) {
303+
func newWatcher(paths []string, ignore PathMatcher) (Notify, error) {
274304
fsw, err := fsnotify.NewWatcher()
275305
if err != nil {
276306
if strings.Contains(err.Error(), "too many open files") && runtime.GOOS == "linux" {
@@ -297,9 +327,9 @@ func newWatcher(paths []string) (Notify, error) {
297327
}
298328
notifyList[path] = true
299329
}
300-
301330
wmw := &naiveNotify{
302331
notifyList: notifyList,
332+
ignore: ignore,
303333
watcher: fsw,
304334
events: fsw.Events,
305335
wrappedEvents: wrappedEvents,

0 commit comments

Comments
 (0)