Skip to content
Snippets Groups Projects
Verified Commit ddb13564 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: Same path added with and without slashes are handled differently #5

parent 6f641cd2
No related branches found
No related tags found
No related merge requests found
...@@ -74,11 +74,11 @@ ...@@ -74,11 +74,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1698288402, "lastModified": 1698434055,
"narHash": "sha256-jIIjApPdm+4yt8PglX8pUOexAdEiAax/DXW3S/Mb21E=", "narHash": "sha256-Phxi5mUKSoL7A0IYUiYtkI9e8NcGaaV5PJEaJApU1Ko=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "60b9db998f71ea49e1a9c41824d09aa274be1344", "rev": "1a3c95e3b23b3cdb26750621c08cc2f1560cb883",
"type": "github" "type": "github"
}, },
"original": { "original": {
...@@ -106,11 +106,11 @@ ...@@ -106,11 +106,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1698288402, "lastModified": 1698434055,
"narHash": "sha256-jIIjApPdm+4yt8PglX8pUOexAdEiAax/DXW3S/Mb21E=", "narHash": "sha256-Phxi5mUKSoL7A0IYUiYtkI9e8NcGaaV5PJEaJApU1Ko=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "60b9db998f71ea49e1a9c41824d09aa274be1344", "rev": "1a3c95e3b23b3cdb26750621c08cc2f1560cb883",
"type": "github" "type": "github"
}, },
"original": { "original": {
......
...@@ -56,3 +56,11 @@ type WatcherAlreadyActiveError struct{} ...@@ -56,3 +56,11 @@ type WatcherAlreadyActiveError struct{}
func (e WatcherAlreadyActiveError) Error() string { func (e WatcherAlreadyActiveError) Error() string {
return "Watcher is already active" return "Watcher is already active"
} }
type PathNotExistingError struct {
Path string
}
func (e PathNotExistingError) Error() string {
return fmt.Sprintf("Path %s does not exist", e.Path)
}
...@@ -3,6 +3,7 @@ package watch ...@@ -3,6 +3,7 @@ package watch
import ( import (
"fmt" "fmt"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
"os"
"path/filepath" "path/filepath"
"sync" "sync"
"time" "time"
...@@ -183,12 +184,38 @@ func (l *lighthouse) IsActive() bool { ...@@ -183,12 +184,38 @@ func (l *lighthouse) IsActive() bool {
return l.active return l.active
} }
// normalizePath returns the normalized path. If the path is a directory, a
// trailing slash is added.
// If the path does not exist, an error is returned.
// If the path is a directory, the second return value is true.
func normalizePath(path string) (string, bool, error) {
isDir := false
fi, err := os.Stat(path)
if err != nil {
return "", isDir, err
}
// normalize is path is directory
if fi.IsDir() {
path = filepath.Clean(path)
isDir = true
}
return path, isDir, nil
}
// Add adds a path to the watcher. If the path is already being watched or the // Add adds a path to the watcher. If the path is already being watched or the
// watcher is not active, an error is returned. // watcher is not active, an error is returned.
func (l *lighthouse) Add(watch *Watch) error { func (l *lighthouse) Add(watch *Watch) error {
l.mutex.Lock() l.mutex.Lock()
defer l.mutex.Unlock() defer l.mutex.Unlock()
var err error
if !l.active { if !l.active {
return LighthouseNotActiveError{} return LighthouseNotActiveError{}
} }
...@@ -197,8 +224,13 @@ func (l *lighthouse) Add(watch *Watch) error { ...@@ -197,8 +224,13 @@ func (l *lighthouse) Add(watch *Watch) error {
return AlreadyWatchedPathError{AlreadyWatched: watch.Path} return AlreadyWatchedPathError{AlreadyWatched: watch.Path}
} }
watch.Path, _, err = normalizePath(watch.Path)
if err != nil {
return err
}
l.watchers[watch.Path] = watch l.watchers[watch.Path] = watch
err := l.fsnotify.Add(watch.Path) err = l.fsnotify.Add(watch.Path)
if err != nil { if err != nil {
return err return err
} }
...@@ -216,6 +248,8 @@ func (l *lighthouse) Remove(path string) error { ...@@ -216,6 +248,8 @@ func (l *lighthouse) Remove(path string) error {
return LighthouseNotActiveError{} return LighthouseNotActiveError{}
} }
path, _, _ = normalizePath(path)
if _, ok := l.watchers[path]; !ok { if _, ok := l.watchers[path]; !ok {
return UnwatchedPathError{UnwatchedPath: path} return UnwatchedPathError{UnwatchedPath: path}
} }
...@@ -249,6 +283,8 @@ func (l *lighthouse) IsWatched(path string) bool { ...@@ -249,6 +283,8 @@ func (l *lighthouse) IsWatched(path string) bool {
return false return false
} }
path, _, _ = normalizePath(path)
if _, ok := l.watchers[path]; !ok { if _, ok := l.watchers[path]; !ok {
return false return false
} }
...@@ -268,10 +304,17 @@ func (l *lighthouse) Get(path string) (*Watch, error) { ...@@ -268,10 +304,17 @@ func (l *lighthouse) Get(path string) (*Watch, error) {
var watch *Watch var watch *Watch
var ok bool var ok bool
var isDir bool
path, isDir, _ = normalizePath(path)
if watch, ok = l.watchers[path]; !ok { if watch, ok = l.watchers[path]; !ok {
if isDir {
return nil, UnwatchedPathError{UnwatchedPath: path}
}
if watch, ok = l.watchers[filepath.Dir(path)]; !ok { dir := filepath.Dir(path)
if watch, ok = l.watchers[dir]; !ok {
return nil, UnwatchedPathError{UnwatchedPath: path} return nil, UnwatchedPathError{UnwatchedPath: path}
} }
...@@ -292,6 +335,8 @@ func (l *lighthouse) IsActiveWatched(path string) bool { ...@@ -292,6 +335,8 @@ func (l *lighthouse) IsActiveWatched(path string) bool {
l.mutex.Lock() l.mutex.Lock()
defer l.mutex.Unlock() defer l.mutex.Unlock()
path, _, _ = normalizePath(path)
// check fsnotify // check fsnotify
for _, fsPath := range l.fsnotify.WatchList() { for _, fsPath := range l.fsnotify.WatchList() {
if fsPath == path { if fsPath == path {
......
...@@ -102,7 +102,7 @@ func TestWatchList(t *testing.T) { ...@@ -102,7 +102,7 @@ func TestWatchList(t *testing.T) {
assert.Equal(t, tempDir, l.WatchList()[0]) assert.Equal(t, tempDir, l.WatchList()[0])
} }
// test isinsync // Test IsInSync with a file that is not watched by fsnotify
func TestIsInSync(t *testing.T) { func TestIsInSync(t *testing.T) {
tempDir, err := os.MkdirTemp("", "watchtest") tempDir, err := os.MkdirTemp("", "watchtest")
assert.Nil(t, err) assert.Nil(t, err)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment