From 6a0b826d4fb1dd872d902e3f413050162f95ce1e Mon Sep 17 00:00:00 2001 From: Volker Schukai <volker.schukai@schukai.com> Date: Mon, 11 Sep 2023 08:39:23 +0200 Subject: [PATCH] feat: implement #1 --- lighthouse.go | 67 +++++++++++++++++++++++++++++++++++++++ lighthouse_test.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) diff --git a/lighthouse.go b/lighthouse.go index bbbe346..40580fd 100644 --- a/lighthouse.go +++ b/lighthouse.go @@ -1,6 +1,7 @@ package watch import ( + "fmt" "github.com/fsnotify/fsnotify" "path/filepath" "sync" @@ -57,6 +58,11 @@ type Lighthouse interface { SetOnError(callback EventErrorCallback) SetDebounce(duration time.Duration) + + WatchList() []string + Sync() error + + IsInSync() bool } // NewLighthouse creates a new lighthouse instance. @@ -102,6 +108,67 @@ func (l *lighthouse) checkAndInit() { } +// WatchList returns a list of all watched paths. +func (l *lighthouse) WatchList() []string { + l.mutex.Lock() + defer l.mutex.Unlock() + var list []string + for k := range l.watchers { + list = append(list, k) + } + return list + +} + +// IsInSync returns true if all paths are watched by fsnotify. +func (l *lighthouse) IsInSync() bool { + l.mutex.Lock() + defer l.mutex.Unlock() + + wl := l.fsnotify.WatchList() + + if len(wl) != len(l.watchers) { + return false + } + + for _, w := range wl { + if _, ok := l.watchers[w]; !ok { + return false + } + } + + return true + +} + +// Sync Lighthouse and fsnotify. Remove all watchers from fsnotify and add them again. +func (l *lighthouse) Sync() error { + l.mutex.Lock() + defer l.mutex.Unlock() + + // remove all watchers from fsnotify + wl := l.fsnotify.WatchList() + for _, w := range wl { + _ = l.fsnotify.Remove(w) + } + + // add all watchers to fsnotify + var errReturn error + + for k := range l.watchers { + err := l.fsnotify.Add(k) + if err != nil { + if errReturn == nil { + errReturn = err + } else { + errReturn = fmt.Errorf("%w, %v", errReturn, err) + } + } + } + + return errReturn +} + // IsRunning returns true if the watcher is active, false otherwise. func (l *lighthouse) IsRunning() bool { l.mutex.Lock() diff --git a/lighthouse_test.go b/lighthouse_test.go index 218ea09..e36aa6c 100644 --- a/lighthouse_test.go +++ b/lighthouse_test.go @@ -84,3 +84,82 @@ func TestIsActiveWatched(t *testing.T) { assert.True(t, l.IsActiveWatched(tempDir)) assert.False(t, l.IsActiveWatched("path/not/watched")) } + +func TestWatchList(t *testing.T) { + tempDir, err := os.MkdirTemp("", "watchtest") + assert.Nil(t, err) + defer func() { + _ = os.RemoveAll(tempDir) // Cleanup + }() + + l := NewLighthouse() + + w := &Watch{Path: tempDir} + err = l.Add(w) + assert.Nil(t, err) + + assert.Equal(t, 1, len(l.WatchList())) + assert.Equal(t, tempDir, l.WatchList()[0]) +} + +// test isinsync +func TestIsInSync(t *testing.T) { + tempDir, err := os.MkdirTemp("", "watchtest") + assert.Nil(t, err) + + tempFile, err := os.CreateTemp(tempDir, "test") + assert.Nil(t, err) + + defer func() { + _ = os.RemoveAll(tempDir) // Cleanup + _ = os.RemoveAll(tempFile.Name()) // Cleanup + }() + + l := NewLighthouse() + + w := &Watch{Path: tempDir} + err = l.Add(w) + assert.Nil(t, err) + + w2 := &Watch{Path: tempFile.Name()} + err = l.Add(w2) + assert.Nil(t, err) + + err = l.Sync() + assert.Nil(t, err) + + assert.True(t, l.IsInSync()) + + internal := l.(*lighthouse) + internal.fsnotify.Remove(tempFile.Name()) + + assert.False(t, l.IsInSync()) + +} + +// test Sync +func TestSync(t *testing.T) { + tempDir, err := os.MkdirTemp("", "watchtest") + assert.Nil(t, err) + + tempFile, err := os.CreateTemp(tempDir, "test") + assert.Nil(t, err) + + defer func() { + _ = os.RemoveAll(tempDir) // Cleanup + _ = os.RemoveAll(tempFile.Name()) // Cleanup + }() + + l := NewLighthouse() + + w := &Watch{Path: tempDir} + err = l.Add(w) + assert.Nil(t, err) + + w2 := &Watch{Path: tempFile.Name()} + err = l.Add(w2) + assert.Nil(t, err) + + err = l.Sync() + assert.Nil(t, err) +} -- GitLab