From ceec78a40cdf544b8a788d52cec53fb2855931be Mon Sep 17 00:00:00 2001 From: Shulhan Date: Wed, 25 Dec 2024 13:49:55 +0700 Subject: lib/watchfs: detach the options from memfs --- lib/watchfs/dirwatcher.go | 51 +++++++++++++++------------------- lib/watchfs/dirwatcher_example_test.go | 5 ++-- lib/watchfs/dirwatcher_options.go | 34 +++++++++++++++++++++++ lib/watchfs/dirwatcher_test.go | 23 ++++++++------- lib/watchfs/watchfs.go | 3 +- 5 files changed, 71 insertions(+), 45 deletions(-) create mode 100644 lib/watchfs/dirwatcher_options.go diff --git a/lib/watchfs/dirwatcher.go b/lib/watchfs/dirwatcher.go index b602de5d..e32f3148 100644 --- a/lib/watchfs/dirwatcher.go +++ b/lib/watchfs/dirwatcher.go @@ -49,23 +49,7 @@ type DirWatcher struct { // key. fileWatcher map[string]*Watcher - // This struct embed Options to map the directory to be watched - // into memory. - // - // The Root field define the directory that we want to watch. - // - // Includes contains list of regex to filter file names that we want - // to be notified. - // - // Excludes contains list of regex to filter file names that we did - // not want to be notified. - Options - - // Delay define a duration when the new changes will be fetched from - // system. - // This field is optional, minimum is 100 milli second and default - // is 5 seconds. - Delay time.Duration + Options DirWatcherOptions // dirsLocker protect adding and removing key in [dirs]. dirsLocker sync.Mutex @@ -80,24 +64,29 @@ type DirWatcher struct { func (dw *DirWatcher) init() (err error) { var logp = `init` - if dw.Delay < 100*time.Millisecond { - dw.Delay = defWatchDelay + if dw.Options.Delay < 100*time.Millisecond { + dw.Options.Delay = defWatchDelay } if dw.fs == nil { var fi fs.FileInfo - fi, err = os.Stat(dw.Root) + fi, err = os.Stat(dw.Options.Root) if err != nil { return fmt.Errorf(`%s: %w`, logp, err) } if !fi.IsDir() { - return fmt.Errorf(`%s: %q is not a directory`, logp, dw.Root) + return fmt.Errorf(`%s: %q is not a directory`, + logp, dw.Options.Root) } - dw.Options.MaxFileSize = -1 - - dw.fs, err = memfs.New(&dw.Options) + var mfsOpts = memfs.Options{ + MaxFileSize: -1, + Root: dw.Options.Root, + Includes: dw.Options.Includes, + Excludes: dw.Options.Excludes, + } + dw.fs, err = memfs.New(&mfsOpts) if err != nil { return fmt.Errorf(`%s: %w`, logp, err) } @@ -344,7 +333,13 @@ func (dw *DirWatcher) onRootCreated() { err error ) - dw.fs, err = memfs.New(&dw.Options) + var mfsOpts = memfs.Options{ + MaxFileSize: -1, + Root: dw.Options.Root, + Includes: dw.Options.Includes, + Excludes: dw.Options.Excludes, + } + dw.fs, err = memfs.New(&mfsOpts) if err != nil { log.Printf("%s: %s", logp, err) return @@ -454,7 +449,7 @@ func (dw *DirWatcher) onUpdateMode(node *Node, newInfo os.FileInfo) { func (dw *DirWatcher) start() { var ( logp = `DirWatcher` - ticker = time.NewTicker(dw.Delay) + ticker = time.NewTicker(dw.Options.Delay) ns NodeState err error @@ -465,7 +460,7 @@ func (dw *DirWatcher) start() { case <-ticker.C: var fi os.FileInfo - fi, err = os.Stat(dw.Root) + fi, err = os.Stat(dw.Options.Root) if err != nil { if os.IsNotExist(err) { if dw.fs != nil { @@ -525,7 +520,7 @@ func (dw *DirWatcher) startWatchingFile(parent, child *Node) (err error) { watcher *Watcher ) - watcher, err = newWatcher(parent, child, dw.Delay, dw.qFileChanges) + watcher, err = newWatcher(parent, child, dw.Options.Delay, dw.qFileChanges) if err != nil { return fmt.Errorf(`%s %q: %w`, logp, child.SysPath, err) } diff --git a/lib/watchfs/dirwatcher_example_test.go b/lib/watchfs/dirwatcher_example_test.go index 850991f4..6f78b947 100644 --- a/lib/watchfs/dirwatcher_example_test.go +++ b/lib/watchfs/dirwatcher_example_test.go @@ -10,7 +10,6 @@ import ( "path/filepath" "time" - "git.sr.ht/~shulhan/pakakeh.go/lib/memfs" "git.sr.ht/~shulhan/pakakeh.go/lib/watchfs" ) @@ -29,7 +28,7 @@ func ExampleDirWatcher() { // contents, including only files with ".adoc" extension and // excluding files with ".html" extension. var dw = &watchfs.DirWatcher{ - Options: memfs.Options{ + Options: watchfs.DirWatcherOptions{ Root: rootDir, Includes: []string{ `assets/.*`, @@ -38,8 +37,8 @@ func ExampleDirWatcher() { Excludes: []string{ `.*\.html$`, }, + Delay: 100 * time.Millisecond, }, - Delay: 100 * time.Millisecond, } err = dw.Start() diff --git a/lib/watchfs/dirwatcher_options.go b/lib/watchfs/dirwatcher_options.go new file mode 100644 index 00000000..e6f5b5d6 --- /dev/null +++ b/lib/watchfs/dirwatcher_options.go @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2024 M. Shulhan +// SPDX-License-Identifier: BSD-3-Clause + +package watchfs + +import ( + "time" +) + +// DirWatcherOptions to create and initialize [DirWatcher]. +// +// The includes and excludes pattern applied relative to the system +// path. +// The Excludes patterns will be applied first before the Includes. +// If the path is not excluded and Includes is empty, it will be +// assumed as included. +type DirWatcherOptions struct { + // The Root field define the directory that we want to watch. + Root string + + // Includes contains list of regex to filter file names that we want + // to be notified. + Includes []string + + // Excludes contains list of regex to filter file names that we did + // not want to be notified. + Excludes []string + + // Delay define a duration when the new changes will be fetched from + // system. + // This field is optional, minimum is 100 milli second and default + // is 5 seconds. + Delay time.Duration +} diff --git a/lib/watchfs/dirwatcher_test.go b/lib/watchfs/dirwatcher_test.go index 88008272..3948bee6 100644 --- a/lib/watchfs/dirwatcher_test.go +++ b/lib/watchfs/dirwatcher_test.go @@ -48,10 +48,10 @@ func TestDirWatcher_renameDirectory(t *testing.T) { } dw = DirWatcher{ - Options: Options{ - Root: rootDir, + Options: DirWatcherOptions{ + Root: rootDir, + Delay: 100 * time.Millisecond, }, - Delay: 100 * time.Millisecond, } err = dw.Start() @@ -106,12 +106,11 @@ func TestDirWatcher_removeDirSymlink(t *testing.T) { dirSub = filepath.Join(dirTmp, `sub`) fileOld = filepath.Join(dirWd, `testdata`, `index.html`) fileNew = filepath.Join(dirSub, `index.html`) - opts = Options{ - Root: dirTmp, - } - dw = DirWatcher{ - Options: opts, - Delay: 100 * time.Millisecond, + dw = DirWatcher{ + Options: DirWatcherOptions{ + Root: dirTmp, + Delay: 100 * time.Millisecond, + }, } got NodeState @@ -195,10 +194,10 @@ func TestDirWatcher_withSymlink(t *testing.T) { // Create the DirWatcher instance and start watching the changes. var dw = DirWatcher{ - Options: Options{ - Root: dirDest, + Options: DirWatcherOptions{ + Root: dirDest, + Delay: 100 * time.Millisecond, }, - Delay: 100 * time.Millisecond, } err = dw.Start() diff --git a/lib/watchfs/watchfs.go b/lib/watchfs/watchfs.go index 5c61318f..5e283371 100644 --- a/lib/watchfs/watchfs.go +++ b/lib/watchfs/watchfs.go @@ -9,6 +9,5 @@ package watchfs import "git.sr.ht/~shulhan/pakakeh.go/lib/memfs" +// Node represent single file or directory. type Node = memfs.Node - -type Options = memfs.Options -- cgit v1.3