67 lines
1.2 KiB
Go
67 lines
1.2 KiB
Go
|
package fs
|
||
|
|
||
|
import (
|
||
|
"io/fs"
|
||
|
"path/filepath"
|
||
|
"time"
|
||
|
|
||
|
"github.com/fsnotify/fsnotify"
|
||
|
log "github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
type Event struct {
|
||
|
File string
|
||
|
Timestamp time.Time
|
||
|
}
|
||
|
|
||
|
func NewWatching(backing FS) (*Watching, error) {
|
||
|
watcher, err := fsnotify.NewWatcher()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &Watching{
|
||
|
watcher: watcher,
|
||
|
backing: backing,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
type Watching struct {
|
||
|
events chan Event
|
||
|
watcher *fsnotify.Watcher
|
||
|
backing FS
|
||
|
}
|
||
|
|
||
|
func (w *Watching) Open(name string) (file fs.File, err error) {
|
||
|
file, err = w.backing.Open(name)
|
||
|
if err == nil {
|
||
|
dir := filepath.Dir(name)
|
||
|
if watchErr := w.watcher.Add(dir); watchErr != nil {
|
||
|
log.Errorf("Failed to watch %s: %v", dir, watchErr)
|
||
|
}
|
||
|
return file, nil
|
||
|
}
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
func (w *Watching) Events() chan Event {
|
||
|
if w.events == nil {
|
||
|
w.events = make(chan Event)
|
||
|
go transportEvents(w.watcher.Events, w.events)
|
||
|
}
|
||
|
return w.events
|
||
|
}
|
||
|
|
||
|
func (w *Watching) Close() error {
|
||
|
return w.watcher.Close()
|
||
|
}
|
||
|
|
||
|
func transportEvents(in <-chan fsnotify.Event, out chan<- Event) {
|
||
|
for ev := range in {
|
||
|
ev.Name = filepath.Base(ev.Name)
|
||
|
out <- Event{
|
||
|
File: ev.Name,
|
||
|
Timestamp: time.Now(),
|
||
|
}
|
||
|
}
|
||
|
}
|