]> go.fuhry.dev Git - fsnotify.git/commitdiff
windows: update watch paths when renaming directories with sub-watches (#370)
authorArne Groskurth <arnegroskurth@users.noreply.github.com>
Sun, 31 Jul 2022 19:16:05 +0000 (21:16 +0200)
committerGitHub <noreply@github.com>
Sun, 31 Jul 2022 19:16:05 +0000 (21:16 +0200)
Fixes #259
Fixes #243

Co-authored-by: Martin Tournoij <martin@arp242.net>
helpers_test.go
integration_test.go
windows.go

index cb2f12125ecd9274203d92fb382cbdea824ffa26..08164fd09461d7ef040a82e20a410e2037ecae40 100644 (file)
@@ -411,6 +411,12 @@ func newEvents(t *testing.T, s string) Events {
        if e, ok := events[runtime.GOOS]; ok {
                return e
        }
+       switch runtime.GOOS {
+       case "freebsd", "netbsd", "openbsd", "dragonfly", "darwin":
+               if e, ok := events["kqueue"]; ok {
+                       return e
+               }
+       }
        return events[""]
 }
 
index 6ae1ae076603fb46652c189fe1f4b26419d26e50..28b846c677d77b6490a9a3ef0412d9ae82f2ff15 100644 (file)
@@ -164,6 +164,36 @@ func TestWatchRename(t *testing.T) {
                        windows:
                                create /renamed
                `},
+
+               {"rename watched directory", func(t *testing.T, w *Watcher, tmp string) {
+                       addWatch(t, w, tmp)
+
+                       dir := filepath.Join(tmp, "dir")
+                       mkdir(t, dir)
+                       addWatch(t, w, dir)
+
+                       mv(t, dir, tmp, "dir-renamed")
+                       touch(t, tmp, "dir-renamed/file")
+               }, `
+                       CREATE   "/dir"           # mkdir
+                       RENAME   "/dir"           # mv
+                       CREATE   "/dir-renamed"
+                       RENAME   "/dir"
+                       CREATE   "/dir/file"      # touch
+
+                       windows:
+                               CREATE       "/dir"                 # mkdir
+                               RENAME       "/dir"                 # mv
+                               CREATE       "/dir-renamed"
+                               CREATE       "/dir-renamed/file"    # touch
+
+                       # TODO: no results for the touch; this is probably a bug; windows
+                       # was fixed in #370.
+                       kqueue:
+                               CREATE               "/dir"           # mkdir
+                               CREATE               "/dir-renamed"   # mv
+                               REMOVE|RENAME        "/dir"
+               `},
        }
 
        for _, tt := range tests {
index ecae0ce1c23cd43b98314ea56bde66a220fe6018..c88990480a9fdd057b596ef46d268e42d3eab4e0 100644 (file)
@@ -14,6 +14,7 @@ import (
        "path/filepath"
        "reflect"
        "runtime"
+       "strings"
        "sync"
        "syscall"
        "unsafe"
@@ -500,6 +501,18 @@ func (w *Watcher) readEvents() {
                        case syscall.FILE_ACTION_RENAMED_OLD_NAME:
                                watch.rename = name
                        case syscall.FILE_ACTION_RENAMED_NEW_NAME:
+                               // Update saved path of all sub-watches.
+                               old := filepath.Join(watch.path, watch.rename)
+                               w.mu.Lock()
+                               for _, watchMap := range w.watches {
+                                       for _, ww := range watchMap {
+                                               if strings.HasPrefix(ww.path, old) {
+                                                       ww.path = filepath.Join(fullname, strings.TrimPrefix(ww.path, old))
+                                               }
+                                       }
+                               }
+                               w.mu.Unlock()
+
                                if watch.names[watch.rename] != 0 {
                                        watch.names[name] |= watch.names[watch.rename]
                                        delete(watch.names, watch.rename)