util: recwatch: Remove last use of core logger
We've cleaned up quite a bit, yay!
This commit is contained in:
@@ -151,9 +151,9 @@ func (obj *ReadFileFunc) Stream(ctx context.Context) error {
|
|||||||
obj.recWatcher = &recwatch.RecWatcher{
|
obj.recWatcher = &recwatch.RecWatcher{
|
||||||
Path: *obj.filename,
|
Path: *obj.filename,
|
||||||
Recurse: false,
|
Recurse: false,
|
||||||
Flags: recwatch.Flags{
|
Opts: []recwatch.Option{
|
||||||
// TODO: add Logf
|
recwatch.Logf(obj.init.Logf),
|
||||||
Debug: obj.init.Debug,
|
recwatch.Debug(obj.init.Debug),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := obj.recWatcher.Init(); err != nil {
|
if err := obj.recWatcher.Init(); err != nil {
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
// Mgmt
|
|
||||||
// Copyright (C) 2013-2024+ James Shubin and the project contributors
|
|
||||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
//
|
|
||||||
// Additional permission under GNU GPL version 3 section 7
|
|
||||||
//
|
|
||||||
// If you modify this program, or any covered work, by linking or combining it
|
|
||||||
// with embedded mcl code and modules (and that the embedded mcl code and
|
|
||||||
// modules which link with this program, contain a copy of their source code in
|
|
||||||
// the authoritative form) containing parts covered by the terms of any other
|
|
||||||
// license, the licensors of this program grant you additional permission to
|
|
||||||
// convey the resulting work. Furthermore, the licensors of this program grant
|
|
||||||
// the original author, James Shubin, additional permission to update this
|
|
||||||
// additional permission if he deems it necessary to achieve the goals of this
|
|
||||||
// additional permission.
|
|
||||||
|
|
||||||
package recwatch
|
|
||||||
|
|
||||||
// Flags contains all the constant flags that recwatch needs.
|
|
||||||
type Flags struct {
|
|
||||||
Debug bool
|
|
||||||
}
|
|
||||||
@@ -32,7 +32,6 @@ package recwatch
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -54,11 +53,13 @@ type Event struct {
|
|||||||
|
|
||||||
// RecWatcher is the struct for the recursive watcher. Run Init() on it.
|
// RecWatcher is the struct for the recursive watcher. Run Init() on it.
|
||||||
type RecWatcher struct {
|
type RecWatcher struct {
|
||||||
Path string // computed path
|
Path string // computed path
|
||||||
Recurse bool // should we watch recursively?
|
Recurse bool // should we watch recursively?
|
||||||
Flags Flags
|
Opts []Option // list of options we use
|
||||||
isDir bool // computed isDir
|
|
||||||
safename string // safe path
|
options *recwatchOptions // computed options
|
||||||
|
isDir bool // computed isDir
|
||||||
|
safename string // safe path
|
||||||
watcher *fsnotify.Watcher
|
watcher *fsnotify.Watcher
|
||||||
watches map[string]struct{}
|
watches map[string]struct{}
|
||||||
events chan Event // one channel for events and err...
|
events chan Event // one channel for events and err...
|
||||||
@@ -69,10 +70,11 @@ type RecWatcher struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewRecWatcher creates an initializes a new recursive watcher.
|
// NewRecWatcher creates an initializes a new recursive watcher.
|
||||||
func NewRecWatcher(path string, recurse bool) (*RecWatcher, error) {
|
func NewRecWatcher(path string, recurse bool, opts ...Option) (*RecWatcher, error) {
|
||||||
obj := &RecWatcher{
|
obj := &RecWatcher{
|
||||||
Path: path,
|
Path: path,
|
||||||
Recurse: recurse,
|
Recurse: recurse,
|
||||||
|
Opts: opts,
|
||||||
}
|
}
|
||||||
return obj, obj.Init()
|
return obj, obj.Init()
|
||||||
}
|
}
|
||||||
@@ -85,6 +87,19 @@ func (obj *RecWatcher) Init() error {
|
|||||||
obj.exit = make(chan struct{})
|
obj.exit = make(chan struct{})
|
||||||
obj.isDir = strings.HasSuffix(obj.Path, "/") // dirs have trailing slashes
|
obj.isDir = strings.HasSuffix(obj.Path, "/") // dirs have trailing slashes
|
||||||
obj.safename = path.Clean(obj.Path) // no trailing slash
|
obj.safename = path.Clean(obj.Path) // no trailing slash
|
||||||
|
obj.options = &recwatchOptions{ // default recwatch options
|
||||||
|
debug: false,
|
||||||
|
logf: func(format string, v ...interface{}) {
|
||||||
|
// noop
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, optionFunc := range obj.Opts { // apply the recwatch options
|
||||||
|
optionFunc(obj.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
if obj.options.logf == nil {
|
||||||
|
return fmt.Errorf("recwatch: logf must not be nil")
|
||||||
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
obj.watcher, err = fsnotify.NewWatcher()
|
obj.watcher, err = fsnotify.NewWatcher()
|
||||||
@@ -163,13 +178,13 @@ func (obj *RecWatcher) Watch() error {
|
|||||||
if current == "" { // the empty string top is the root dir ("/")
|
if current == "" { // the empty string top is the root dir ("/")
|
||||||
current = "/"
|
current = "/"
|
||||||
}
|
}
|
||||||
if obj.Flags.Debug {
|
if obj.options.debug {
|
||||||
log.Printf("watching: %s", current) // attempting to watch...
|
obj.options.logf("watching: %s", current) // attempting to watch...
|
||||||
}
|
}
|
||||||
// initialize in the loop so that we can reset on rm-ed handles
|
// initialize in the loop so that we can reset on rm-ed handles
|
||||||
if err := obj.watcher.Add(current); err != nil {
|
if err := obj.watcher.Add(current); err != nil {
|
||||||
if obj.Flags.Debug {
|
if obj.options.debug {
|
||||||
log.Printf("watcher.Add(%s): Error: %v", current, err)
|
obj.options.logf("watcher.Add(%s): Error: %v", current, err)
|
||||||
}
|
}
|
||||||
// ENOENT for linux, etc and IsNotExist for macOS
|
// ENOENT for linux, etc and IsNotExist for macOS
|
||||||
if err == syscall.ENOENT || os.IsNotExist(err) {
|
if err == syscall.ENOENT || os.IsNotExist(err) {
|
||||||
@@ -191,8 +206,8 @@ func (obj *RecWatcher) Watch() error {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case event := <-obj.watcher.Events:
|
case event := <-obj.watcher.Events:
|
||||||
if obj.Flags.Debug {
|
if obj.options.debug {
|
||||||
log.Printf("watch(%s), event(%s): %v", current, event.Name, event.Op)
|
obj.options.logf("watch(%s), event(%s): %v", current, event.Name, event.Op)
|
||||||
}
|
}
|
||||||
// the deeper you go, the bigger the deltaDepth is...
|
// the deeper you go, the bigger the deltaDepth is...
|
||||||
// this is the difference between what we're watching,
|
// this is the difference between what we're watching,
|
||||||
@@ -228,11 +243,11 @@ func (obj *RecWatcher) Watch() error {
|
|||||||
// event.Name: /tmp/mgmt/f3 and current: /tmp/mgmt/f2
|
// event.Name: /tmp/mgmt/f3 and current: /tmp/mgmt/f2
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//log.Printf("the delta depth is: %v", deltaDepth)
|
//obj.options.logf("the delta depth is: %v", deltaDepth)
|
||||||
|
|
||||||
// if we have what we wanted, awesome, send an event...
|
// if we have what we wanted, awesome, send an event...
|
||||||
if event.Name == obj.safename {
|
if event.Name == obj.safename {
|
||||||
//log.Printf("event!")
|
//obj.options.logf("event!")
|
||||||
// FIXME: should all these below cases trigger?
|
// FIXME: should all these below cases trigger?
|
||||||
send = true
|
send = true
|
||||||
|
|
||||||
@@ -244,7 +259,7 @@ func (obj *RecWatcher) Watch() error {
|
|||||||
|
|
||||||
// file removed, move the watch upwards
|
// file removed, move the watch upwards
|
||||||
if deltaDepth >= 0 && (event.Op&fsnotify.Remove == fsnotify.Remove) {
|
if deltaDepth >= 0 && (event.Op&fsnotify.Remove == fsnotify.Remove) {
|
||||||
//log.Printf("removal!")
|
//obj.options.logf("removal!")
|
||||||
obj.watcher.Remove(current)
|
obj.watcher.Remove(current)
|
||||||
index--
|
index--
|
||||||
}
|
}
|
||||||
@@ -265,16 +280,16 @@ func (obj *RecWatcher) Watch() error {
|
|||||||
|
|
||||||
// if safename starts with event.Name, we're above, and no event should be sent
|
// if safename starts with event.Name, we're above, and no event should be sent
|
||||||
} else if util.HasPathPrefix(obj.safename, event.Name) {
|
} else if util.HasPathPrefix(obj.safename, event.Name) {
|
||||||
//log.Printf("above!")
|
//obj.options.logf("above!")
|
||||||
|
|
||||||
if deltaDepth >= 0 && (event.Op&fsnotify.Remove == fsnotify.Remove) {
|
if deltaDepth >= 0 && (event.Op&fsnotify.Remove == fsnotify.Remove) {
|
||||||
log.Printf("removal!")
|
//obj.options.logf("removal!")
|
||||||
obj.watcher.Remove(current)
|
obj.watcher.Remove(current)
|
||||||
index--
|
index--
|
||||||
}
|
}
|
||||||
|
|
||||||
if deltaDepth < 0 {
|
if deltaDepth < 0 {
|
||||||
log.Printf("parent!")
|
//obj.options.logf("parent!")
|
||||||
if util.PathPrefixDelta(obj.safename, event.Name) == 1 { // we're the parent dir
|
if util.PathPrefixDelta(obj.safename, event.Name) == 1 { // we're the parent dir
|
||||||
send = true
|
send = true
|
||||||
}
|
}
|
||||||
@@ -284,7 +299,7 @@ func (obj *RecWatcher) Watch() error {
|
|||||||
|
|
||||||
// if event.Name startswith safename, send event, we're already deeper
|
// if event.Name startswith safename, send event, we're already deeper
|
||||||
} else if util.HasPathPrefix(event.Name, obj.safename) {
|
} else if util.HasPathPrefix(event.Name, obj.safename) {
|
||||||
//log.Printf("event2!")
|
//obj.options.logf("event2!")
|
||||||
send = true
|
send = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,8 +332,8 @@ func (obj *RecWatcher) addSubFolders(p string) error {
|
|||||||
}
|
}
|
||||||
// look at all subfolders...
|
// look at all subfolders...
|
||||||
walkFn := func(path string, info os.FileInfo, err error) error {
|
walkFn := func(path string, info os.FileInfo, err error) error {
|
||||||
if obj.Flags.Debug {
|
if obj.options.debug {
|
||||||
log.Printf("walk: %s (%v): %v", path, info, err)
|
obj.options.logf("walk: %s (%v): %v", path, info, err)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -336,6 +351,29 @@ func (obj *RecWatcher) addSubFolders(p string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option is a type that can be used to configure the recwatcher.
|
||||||
|
type Option func(*recwatchOptions)
|
||||||
|
|
||||||
|
type recwatchOptions struct {
|
||||||
|
debug bool
|
||||||
|
logf func(format string, v ...interface{})
|
||||||
|
// TODO: add more options
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug specifies whether we should run in debug mode or not.
|
||||||
|
func Debug(debug bool) Option {
|
||||||
|
return func(rwo *recwatchOptions) {
|
||||||
|
rwo.debug = debug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logf passes a logger function that we can use if so desired.
|
||||||
|
func Logf(logf func(format string, v ...interface{})) Option {
|
||||||
|
return func(rwo *recwatchOptions) {
|
||||||
|
rwo.logf = logf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func isDir(path string) bool {
|
func isDir(path string) bool {
|
||||||
finfo, err := os.Stat(path)
|
finfo, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user