Signed-off-by: Naman Sood <mail@nsood.in>
This commit is contained in:
parent
18455362d3
commit
1981a291aa
17 changed files with 916 additions and 849 deletions
119
watcher/watcher.go
Normal file
119
watcher/watcher.go
Normal file
|
@ -0,0 +1,119 @@
|
|||
package watcher
|
||||
|
||||
import (
|
||||
"iter"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/rjeczalik/notify"
|
||||
)
|
||||
|
||||
type WatchEventKind int
|
||||
|
||||
const (
|
||||
Update WatchEventKind = iota
|
||||
Clean
|
||||
)
|
||||
|
||||
// WatchEvent represents a change to a watched folder. It notes which file
|
||||
// changed and what change happened to it.
|
||||
type WatchEvent struct {
|
||||
File string
|
||||
Kind WatchEventKind
|
||||
}
|
||||
|
||||
func updated(f string) *WatchEvent {
|
||||
return &WatchEvent{
|
||||
File: f,
|
||||
Kind: Update,
|
||||
}
|
||||
}
|
||||
|
||||
func cleaned(f string) *WatchEvent {
|
||||
return &WatchEvent{
|
||||
File: f,
|
||||
Kind: Clean,
|
||||
}
|
||||
}
|
||||
|
||||
// Watcher classifies notify.Events into updates and deletes, and calls the
|
||||
// respective functions for a file when those events happen to that file.
|
||||
func Watch(folder string, up Updater[string]) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal("could not get current working directory for listener!")
|
||||
}
|
||||
cwd = cwd + "/"
|
||||
|
||||
c := make(chan notify.EventInfo, 1)
|
||||
|
||||
var events []notify.Event
|
||||
|
||||
// inotify events prevent double-firing of
|
||||
// certain events in Linux.
|
||||
if runtime.GOOS == "linux" {
|
||||
events = []notify.Event{
|
||||
notify.InCloseWrite,
|
||||
notify.InMovedFrom,
|
||||
notify.InMovedTo,
|
||||
notify.InDelete,
|
||||
}
|
||||
} else {
|
||||
events = []notify.Event{
|
||||
notify.Create,
|
||||
notify.Remove,
|
||||
notify.Rename,
|
||||
notify.Write,
|
||||
}
|
||||
}
|
||||
|
||||
err = notify.Watch(folder, c, events...)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("could not setup watcher for folder %s: %s", folder, err)
|
||||
}
|
||||
|
||||
defer notify.Stop(c)
|
||||
for {
|
||||
ei := <-c
|
||||
log.Printf("event: %s", ei.Event())
|
||||
switch ei.Event() {
|
||||
case notify.InCloseWrite, notify.InMovedTo, notify.Create, notify.Rename, notify.Write:
|
||||
filePath := strings.TrimPrefix(ei.Path(), cwd)
|
||||
log.Printf("updating file %s", filePath)
|
||||
err := up.Fetch(strings.TrimPrefix(filePath, folder))
|
||||
if err != nil {
|
||||
log.Printf("up.Fetch(%q): %v", filePath, err)
|
||||
}
|
||||
case notify.InMovedFrom, notify.InDelete, notify.Remove:
|
||||
filePath := strings.TrimPrefix(ei.Path(), cwd)
|
||||
log.Printf("cleaning file %s", filePath)
|
||||
err := up.Delete(strings.TrimPrefix(filePath, folder))
|
||||
if err != nil {
|
||||
log.Printf("up.Delete(%q): %v", filePath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Updater is a key-value store which can be informed when to recompute values
|
||||
// for a particular key. Updaters are normally also AutoMaps.
|
||||
type Updater[K any] interface {
|
||||
Fetch(K) error
|
||||
Delete(K) error
|
||||
}
|
||||
|
||||
// AutoMap is a key-value store where the values are automatically computed by
|
||||
// the store itself, based on the key.
|
||||
type AutoMap[K, V any] interface {
|
||||
Get(K) (V, bool)
|
||||
}
|
||||
|
||||
// OrderedAutoMap is an AutoMap that provides an iterator over its
|
||||
// currently-existing keys in a known order.
|
||||
type OrderedAutoMap[K, V any] interface {
|
||||
AutoMap[K, V]
|
||||
All() iter.Seq2[K, V]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue