Skip to content

Commit

Permalink
Merge pull request #889 from Shopify/dir_event_catching
Browse files Browse the repository at this point in the history
Fixing folder events in file watcher
  • Loading branch information
tanema authored Feb 3, 2021
2 parents 061d658 + e964da8 commit 250a58f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 9 deletions.
20 changes: 11 additions & 9 deletions src/file/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,14 @@ func (w *Watcher) watchFsEvents() {
}

func (w *Watcher) onEvent(event watcher.Event) bool {
if event.IsDir() {
if isEventType(event.Op, watcher.Create) {
w.fsWatcher.Add(event.Path)
}
return false
}
events := map[string]Event{}
for _, event := range w.translateEvent(event) {
events[event.Path] = event
for _, e := range w.translateEvent(event) {
events[e.Path] = e
}
if len(events) == 0 {
return false
}

drainTimer := time.NewTimer(drainTimeout)
defer drainTimer.Stop()
for {
Expand Down Expand Up @@ -164,7 +162,11 @@ func (w *Watcher) updateChecksum(e Event) {

func (w *Watcher) translateEvent(event watcher.Event) []Event {
oldPath, currentPath := w.parsePath(event.OldPath), w.parsePath(event.Path)
if isEventType(event.Op, watcher.Rename, watcher.Move) {
if event.IsDir() {
if isEventType(event.Op, watcher.Create) {
w.fsWatcher.Add(event.Path)
}
} else if isEventType(event.Op, watcher.Rename, watcher.Move) {
return []Event{{Op: Remove, Path: oldPath}, {Op: Update, Path: currentPath, LastKnownChecksum: w.checksums[currentPath]}}
} else if isEventType(event.Op, watcher.Remove) {
return []Event{{Op: Remove, Path: currentPath}}
Expand Down
37 changes: 37 additions & 0 deletions src/file/watcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,43 @@ func TestFileWatcher_OnEvent(t *testing.T) {
}
}

func TestFileWatcher_translateEvent(t *testing.T) {
testcases := []struct {
filename, oldname string
op watcher.Op
expectedOp OptSlice
}{
{expectedOp: OptSlice{Update}, filename: "_testdata/project/templates/template.liquid", op: watcher.Write},
{expectedOp: OptSlice{Update}, filename: "_testdata/project/templates/customers/test.liquid", op: watcher.Create},
{expectedOp: OptSlice{}, filename: "_testdata/project/config", op: watcher.Create},
{expectedOp: OptSlice{Remove}, filename: "_testdata/project/templates/customers/test.liquid", op: watcher.Remove},
{expectedOp: OptSlice{Remove, Update}, filename: "_testdata/project/assets/application.js.liquid", oldname: "_testdata/project/assets/application.js", op: watcher.Rename},
{expectedOp: OptSlice{Remove, Update}, filename: "_testdata/project/assets/application.js.liquid", oldname: "_testdata/project/assets/application.js", op: watcher.Move},
}

for _, testcase := range testcases {
info, _ := os.Stat(testcase.filename)
evt := watcher.Event{
Op: testcase.op,
Path: testcase.filename,
OldPath: testcase.oldname,
FileInfo: info,
}

w := createTestWatcher(t)
events := w.translateEvent(evt)
assert.Equal(t, len(testcase.expectedOp), len(events))
recievedEvents := OptSlice{}
for _, e := range events {
recievedEvents = append(recievedEvents, e.Op)
}
sort.Sort(testcase.expectedOp)
sort.Sort(recievedEvents)
assert.Equal(t, testcase.expectedOp, recievedEvents)
w.Stop()
}
}

func TestFileWatcher_debouncing(t *testing.T) {
w := createTestWatcher(t)
w.Events = make(chan Event, 10)
Expand Down

0 comments on commit 250a58f

Please sign in to comment.