util: recwatch: Remove last use of core logger

We've cleaned up quite a bit, yay!
This commit is contained in:
James Shubin
2024-03-22 02:21:19 -04:00
parent 3541954df8
commit 43b5a0ea6a
3 changed files with 63 additions and 60 deletions

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -32,7 +32,6 @@ package recwatch
import ( import (
"fmt" "fmt"
"log"
"math" "math"
"os" "os"
"path" "path"
@@ -56,7 +55,9 @@ type Event struct {
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
options *recwatchOptions // computed options
isDir bool // computed isDir isDir bool // computed isDir
safename string // safe path safename string // safe path
watcher *fsnotify.Watcher watcher *fsnotify.Watcher
@@ -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 {