Skip to content

Commit 9429b3d

Browse files
committed
feat: multiple-watch directory support
1 parent 8465e39 commit 9429b3d

File tree

2 files changed

+64
-40
lines changed

2 files changed

+64
-40
lines changed

main.go

+10-18
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,11 @@ func main() {
4444
EnvVars: []string{},
4545
TakesFile: false,
4646
},
47-
&cli.PathFlag{
47+
&cli.StringSliceFlag{
4848
Name: "dir",
4949
Usage: "directory to watch on",
5050
Required: false,
51-
Value: func() string {
52-
cwd, err := os.Getwd()
53-
if err != nil {
54-
panic(err)
55-
}
56-
return cwd
57-
}(),
58-
Aliases: []string{"d"},
51+
Aliases: []string{"d"},
5952
},
6053
&cli.StringSliceFlag{
6154
Name: "ignore-suffixes",
@@ -64,7 +57,7 @@ func main() {
6457
Aliases: []string{"i"},
6558
},
6659
&cli.StringSliceFlag{
67-
Name: "only-watch-suffixes",
60+
Name: "only-suffixes",
6861
Usage: "files suffixes to watch",
6962
Required: false,
7063
Aliases: []string{"w"},
@@ -73,7 +66,7 @@ func main() {
7366
Name: "exclude-dir",
7467
Usage: "directory to exclude from watching",
7568
Required: false,
76-
Aliases: []string{"x", "e"},
69+
Aliases: []string{"x"},
7770
},
7871
&cli.BoolFlag{
7972
Name: "no-default-ignore",
@@ -134,8 +127,10 @@ func main() {
134127
})
135128

136129
watcher, err := fswatcher.NewWatcher(fswatcher.WatcherArgs{
137-
Logger: logger,
138-
OnlyWatchSuffixes: cctx.StringSlice("only-watch-suffixes"),
130+
Logger: logger,
131+
132+
WatchDirs: cctx.StringSlice("dir"),
133+
OnlySuffixes: cctx.StringSlice("only-suffixes"),
139134
IgnoreSuffixes: cctx.StringSlice("ignore-suffixes"),
140135
ExcludeDirs: cctx.StringSlice("exclude-dir"),
141136
UseDefaultIgnoreList: !cctx.Bool("no-global-ignore"),
@@ -144,10 +139,6 @@ func main() {
144139
panic(err)
145140
}
146141

147-
if err := watcher.RecursiveAdd(cctx.String("dir")); err != nil {
148-
panic(err)
149-
}
150-
151142
go ex.Exec()
152143

153144
go func() {
@@ -157,8 +148,9 @@ func main() {
157148
os.Exit(0)
158149
}()
159150

151+
pwd, _ := os.Getwd()
160152
watcher.WatchEvents(func(event fswatcher.Event, fp string) error {
161-
relPath, err := filepath.Rel(cctx.String("dir"), fp)
153+
relPath, err := filepath.Rel(pwd, fp)
162154
if err != nil {
163155
return err
164156
}

pkg/watcher/watcher.go

+54-22
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,17 @@ type eventInfo struct {
2424
}
2525

2626
type fsnWatcher struct {
27-
watcher *fsnotify.Watcher
28-
eventMap map[string]eventInfo
27+
watcher *fsnotify.Watcher
2928

3029
directoryCount int
3130

32-
Logger *slog.Logger
33-
OnlyWatchSuffixes []string
34-
IgnoreSuffixes []string
35-
ExcludeDirs map[string]struct{}
31+
Logger *slog.Logger
32+
OnlySuffixes []string
33+
IgnoreSuffixes []string
34+
ExcludeDirs map[string]struct{}
35+
watchingDirs map[string]struct{}
36+
37+
cooldownDuration time.Duration
3638
}
3739

3840
type Event fsnotify.Event
@@ -71,13 +73,13 @@ func (f fsnWatcher) ignoreEvent(event fsnotify.Event) (ignore bool, reason strin
7173
}
7274
}
7375

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

7880
matched := false
79-
for _, suffix := range f.OnlyWatchSuffixes {
80-
f.Logger.Debug("[only-watch-suffix] suffix: (%s), event.name: %s", suffix, event.Name)
81+
for _, suffix := range f.OnlySuffixes {
82+
f.Logger.Debug(fmt.Sprintf("[only-suffix] suffix: (%s), event.name: %s", suffix, event.Name))
8183
if strings.HasSuffix(event.Name, suffix) {
8284
matched = true
8385
break
@@ -123,8 +125,8 @@ func (f *fsnWatcher) WatchEvents(watcherFunc func(event Event, fp string) error)
123125
// eInfo.Counter += 1
124126
// f.eventMap[event.Name] = eInfo
125127

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

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

187189
func (f *fsnWatcher) addToWatchList(dir string) error {
190+
if _, ok := f.watchingDirs[dir]; ok {
191+
return nil
192+
}
193+
194+
f.watchingDirs[dir] = struct{}{}
188195
if err := f.watcher.Add(dir); err != nil {
189196
f.Logger.Error("failed to add directory", "dir", dir, "err", err)
190197
return err
@@ -199,11 +206,16 @@ func (f *fsnWatcher) Close() error {
199206
}
200207

201208
type WatcherArgs struct {
202-
Logger *slog.Logger
203-
OnlyWatchSuffixes []string
204-
IgnoreSuffixes []string
205-
ExcludeDirs []string
209+
Logger *slog.Logger
210+
211+
WatchDirs []string
212+
OnlySuffixes []string
213+
IgnoreSuffixes []string
214+
ExcludeDirs []string
215+
206216
UseDefaultIgnoreList bool
217+
218+
CooldownDuration *time.Duration
207219
}
208220

209221
func NewWatcher(args WatcherArgs) (Watcher, error) {
@@ -215,6 +227,12 @@ func NewWatcher(args WatcherArgs) (Watcher, error) {
215227
args.ExcludeDirs = append(args.ExcludeDirs, globalExcludeDirs...)
216228
}
217229

230+
cooldown := 500 * time.Millisecond
231+
232+
if args.CooldownDuration != nil {
233+
cooldown = *args.CooldownDuration
234+
}
235+
218236
excludeDirs := map[string]struct{}{}
219237
for _, dir := range args.ExcludeDirs {
220238
excludeDirs[dir] = struct{}{}
@@ -225,11 +243,25 @@ func NewWatcher(args WatcherArgs) (Watcher, error) {
225243
args.Logger.Error("failed to create watcher, got", "err", err)
226244
return nil, err
227245
}
228-
return &fsnWatcher{
229-
watcher: watcher,
230-
Logger: args.Logger,
231-
ExcludeDirs: excludeDirs,
232-
IgnoreSuffixes: args.IgnoreSuffixes,
233-
OnlyWatchSuffixes: args.OnlyWatchSuffixes,
234-
}, nil
246+
247+
if args.WatchDirs == nil {
248+
dir, _ := os.Getwd()
249+
args.WatchDirs = append(args.WatchDirs, dir)
250+
}
251+
252+
fsw := &fsnWatcher{
253+
watcher: watcher,
254+
Logger: args.Logger,
255+
ExcludeDirs: excludeDirs,
256+
IgnoreSuffixes: args.IgnoreSuffixes,
257+
OnlySuffixes: args.OnlySuffixes,
258+
cooldownDuration: cooldown,
259+
watchingDirs: make(map[string]struct{}),
260+
}
261+
262+
if err := fsw.RecursiveAdd(args.WatchDirs...); err != nil {
263+
return nil, err
264+
}
265+
266+
return fsw, nil
235267
}

0 commit comments

Comments
 (0)