Skip to content

Commit

Permalink
feat: multiple-watch directory support
Browse files Browse the repository at this point in the history
  • Loading branch information
nxtcoder17 committed Dec 12, 2024
1 parent 8465e39 commit 9429b3d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 40 deletions.
28 changes: 10 additions & 18 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,11 @@ func main() {
EnvVars: []string{},
TakesFile: false,
},
&cli.PathFlag{
&cli.StringSliceFlag{
Name: "dir",
Usage: "directory to watch on",
Required: false,
Value: func() string {
cwd, err := os.Getwd()
if err != nil {
panic(err)
}
return cwd
}(),
Aliases: []string{"d"},
Aliases: []string{"d"},
},
&cli.StringSliceFlag{
Name: "ignore-suffixes",
Expand All @@ -64,7 +57,7 @@ func main() {
Aliases: []string{"i"},
},
&cli.StringSliceFlag{
Name: "only-watch-suffixes",
Name: "only-suffixes",
Usage: "files suffixes to watch",
Required: false,
Aliases: []string{"w"},
Expand All @@ -73,7 +66,7 @@ func main() {
Name: "exclude-dir",
Usage: "directory to exclude from watching",
Required: false,
Aliases: []string{"x", "e"},
Aliases: []string{"x"},
},
&cli.BoolFlag{
Name: "no-default-ignore",
Expand Down Expand Up @@ -134,8 +127,10 @@ func main() {
})

watcher, err := fswatcher.NewWatcher(fswatcher.WatcherArgs{
Logger: logger,
OnlyWatchSuffixes: cctx.StringSlice("only-watch-suffixes"),
Logger: logger,

WatchDirs: cctx.StringSlice("dir"),
OnlySuffixes: cctx.StringSlice("only-suffixes"),
IgnoreSuffixes: cctx.StringSlice("ignore-suffixes"),
ExcludeDirs: cctx.StringSlice("exclude-dir"),
UseDefaultIgnoreList: !cctx.Bool("no-global-ignore"),
Expand All @@ -144,10 +139,6 @@ func main() {
panic(err)
}

if err := watcher.RecursiveAdd(cctx.String("dir")); err != nil {
panic(err)
}

go ex.Exec()

go func() {
Expand All @@ -157,8 +148,9 @@ func main() {
os.Exit(0)
}()

pwd, _ := os.Getwd()
watcher.WatchEvents(func(event fswatcher.Event, fp string) error {
relPath, err := filepath.Rel(cctx.String("dir"), fp)
relPath, err := filepath.Rel(pwd, fp)
if err != nil {
return err
}
Expand Down
76 changes: 54 additions & 22 deletions pkg/watcher/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,17 @@ type eventInfo struct {
}

type fsnWatcher struct {
watcher *fsnotify.Watcher
eventMap map[string]eventInfo
watcher *fsnotify.Watcher

directoryCount int

Logger *slog.Logger
OnlyWatchSuffixes []string
IgnoreSuffixes []string
ExcludeDirs map[string]struct{}
Logger *slog.Logger
OnlySuffixes []string
IgnoreSuffixes []string
ExcludeDirs map[string]struct{}
watchingDirs map[string]struct{}

cooldownDuration time.Duration
}

type Event fsnotify.Event
Expand Down Expand Up @@ -71,13 +73,13 @@ func (f fsnWatcher) ignoreEvent(event fsnotify.Event) (ignore bool, reason strin
}
}

if len(f.OnlyWatchSuffixes) == 0 {
if len(f.OnlySuffixes) == 0 {
return false, "event not in ignore list, and only-watch list is also empty"
}

matched := false
for _, suffix := range f.OnlyWatchSuffixes {
f.Logger.Debug("[only-watch-suffix] suffix: (%s), event.name: %s", suffix, event.Name)
for _, suffix := range f.OnlySuffixes {
f.Logger.Debug(fmt.Sprintf("[only-suffix] suffix: (%s), event.name: %s", suffix, event.Name))
if strings.HasSuffix(event.Name, suffix) {
matched = true
break
Expand Down Expand Up @@ -123,8 +125,8 @@ func (f *fsnWatcher) WatchEvents(watcherFunc func(event Event, fp string) error)
// eInfo.Counter += 1
// f.eventMap[event.Name] = eInfo

if time.Since(lastProcessingTime) < 100*time.Millisecond {
// f.Logger.Debug("too many events under 100ms, ignoring...", "counter", eInfo.Counter)
if time.Since(lastProcessingTime) < f.cooldownDuration {
f.Logger.Debug(fmt.Sprintf("too many events under %s, ignoring...", f.cooldownDuration.String()), "event.name", event.Name)
continue
}

Expand Down Expand Up @@ -185,6 +187,11 @@ func (f *fsnWatcher) RecursiveAdd(dirs ...string) error {
}

func (f *fsnWatcher) addToWatchList(dir string) error {
if _, ok := f.watchingDirs[dir]; ok {
return nil
}

f.watchingDirs[dir] = struct{}{}
if err := f.watcher.Add(dir); err != nil {
f.Logger.Error("failed to add directory", "dir", dir, "err", err)
return err
Expand All @@ -199,11 +206,16 @@ func (f *fsnWatcher) Close() error {
}

type WatcherArgs struct {
Logger *slog.Logger
OnlyWatchSuffixes []string
IgnoreSuffixes []string
ExcludeDirs []string
Logger *slog.Logger

WatchDirs []string
OnlySuffixes []string
IgnoreSuffixes []string
ExcludeDirs []string

UseDefaultIgnoreList bool

CooldownDuration *time.Duration
}

func NewWatcher(args WatcherArgs) (Watcher, error) {
Expand All @@ -215,6 +227,12 @@ func NewWatcher(args WatcherArgs) (Watcher, error) {
args.ExcludeDirs = append(args.ExcludeDirs, globalExcludeDirs...)
}

cooldown := 500 * time.Millisecond

if args.CooldownDuration != nil {
cooldown = *args.CooldownDuration
}

excludeDirs := map[string]struct{}{}
for _, dir := range args.ExcludeDirs {
excludeDirs[dir] = struct{}{}
Expand All @@ -225,11 +243,25 @@ func NewWatcher(args WatcherArgs) (Watcher, error) {
args.Logger.Error("failed to create watcher, got", "err", err)
return nil, err
}
return &fsnWatcher{
watcher: watcher,
Logger: args.Logger,
ExcludeDirs: excludeDirs,
IgnoreSuffixes: args.IgnoreSuffixes,
OnlyWatchSuffixes: args.OnlyWatchSuffixes,
}, nil

if args.WatchDirs == nil {
dir, _ := os.Getwd()
args.WatchDirs = append(args.WatchDirs, dir)
}

fsw := &fsnWatcher{
watcher: watcher,
Logger: args.Logger,
ExcludeDirs: excludeDirs,
IgnoreSuffixes: args.IgnoreSuffixes,
OnlySuffixes: args.OnlySuffixes,
cooldownDuration: cooldown,
watchingDirs: make(map[string]struct{}),
}

if err := fsw.RecursiveAdd(args.WatchDirs...); err != nil {
return nil, err
}

return fsw, nil
}

0 comments on commit 9429b3d

Please sign in to comment.