diff options
author | Alan Pearce | 2024-05-03 00:10:23 +0200 |
---|---|---|
committer | Alan Pearce | 2024-05-03 00:13:51 +0200 |
commit | 8411fb4a3acebe46acaf7a2ff6c4e58018737d65 (patch) | |
tree | 17ea0df23a5b393c42f3e9fb003dc7ef1b27ecf0 /internal/server/dev.go | |
parent | 73603079e29bc89c54296a9e12b5a779cd84c023 (diff) | |
download | searchix-8411fb4a3acebe46acaf7a2ff6c4e58018737d65.tar.lz searchix-8411fb4a3acebe46acaf7a2ff6c4e58018737d65.tar.zst searchix-8411fb4a3acebe46acaf7a2ff6c4e58018737d65.zip |
feat: watch and live reload in development
Diffstat (limited to 'internal/server/dev.go')
-rw-r--r-- | internal/server/dev.go | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/internal/server/dev.go b/internal/server/dev.go new file mode 100644 index 0000000..52ab29b --- /dev/null +++ b/internal/server/dev.go @@ -0,0 +1,71 @@ +package server + +import ( + "fmt" + "io/fs" + "log/slog" + "os" + "path/filepath" + "time" + + "github.com/fsnotify/fsnotify" + "github.com/pkg/errors" +) + +type FileWatcher struct { + *fsnotify.Watcher +} + +func NewFileWatcher() (*FileWatcher, error) { + watcher, err := fsnotify.NewWatcher() + if err != nil { + return nil, errors.WithMessage(err, "could not create watcher") + } + + return &FileWatcher{watcher}, nil +} + +func (watcher FileWatcher) AddRecursive(from string) error { + slog.Debug(fmt.Sprintf("watching files under %s", from)) + err := filepath.WalkDir(from, func(path string, entry fs.DirEntry, err error) error { + if err != nil { + return errors.WithMessagef(err, "could not walk directory %s", path) + } + if entry.IsDir() { + slog.Debug(fmt.Sprintf("adding directory %s to watcher", path)) + if err = watcher.Add(path); err != nil { + return errors.WithMessagef(err, "could not add directory %s to watcher", path) + } + } + + return nil + }) + + return errors.WithMessage(err, "error walking directory tree") +} + +func (watcher FileWatcher) Start(callback func()) { + for { + select { + case event := <-watcher.Events: + slog.Debug(fmt.Sprintf("event received: %s", event)) + if event.Has(fsnotify.Create) || event.Has(fsnotify.Rename) { + f, err := os.Stat(event.Name) + if err != nil { + slog.Error(fmt.Sprintf("error handling %s event: %v", event.Op.String(), err)) + } else if f.IsDir() { + err = watcher.Add(event.Name) + if err != nil { + slog.Error(fmt.Sprintf("error adding new folder to watcher: %v", err)) + } + } + } + if event.Has(fsnotify.Rename) || event.Has(fsnotify.Write) { + callback() + time.Sleep(500 * time.Millisecond) + } + case err := <-watcher.Errors: + slog.Error(fmt.Sprintf("error in watcher: %v", err)) + } + } +} |