mirror of https://bitbucket.org/ausocean/av.git
80 lines
2.1 KiB
Go
80 lines
2.1 KiB
Go
|
/*
|
||
|
DESCRIPTION
|
||
|
|
||
|
watcher.go provides a tool for watching a file for modifications and
|
||
|
performing an action when the file is modified.
|
||
|
|
||
|
AUTHORS
|
||
|
|
||
|
Saxon A. Nelson-Milton <saxon@ausocean.org>
|
||
|
|
||
|
LICENSE
|
||
|
|
||
|
Copyright (C) 2022 the Australian Ocean Lab (AusOcean)
|
||
|
|
||
|
It is free software: you can redistribute it and/or modify them
|
||
|
under the terms of the GNU General Public License as published by the
|
||
|
Free Software Foundation, either version 3 of the License, or (at your
|
||
|
option) any later version.
|
||
|
|
||
|
It is distributed in the hope that it will be useful, but WITHOUT
|
||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||
|
for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
|
||
|
*/
|
||
|
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"path"
|
||
|
|
||
|
"bitbucket.org/ausocean/utils/logging"
|
||
|
"github.com/fsnotify/fsnotify"
|
||
|
)
|
||
|
|
||
|
// watchFile watches a file for modifications and calls onWrite when the file
|
||
|
// is modified. Technically, the directory is watched instead of the file.
|
||
|
// This is because watching the file itself will cause problems if changes
|
||
|
// are done atomically.
|
||
|
// See fsnotify documentation:
|
||
|
// https://godocs.io/github.com/fsnotify/fsnotify#hdr-Watching_files
|
||
|
func watchFile(file string, onWrite func(), l logging.Logger) error {
|
||
|
watcher, err := fsnotify.NewWatcher()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("could not create watcher: %w", err)
|
||
|
}
|
||
|
|
||
|
go func() {
|
||
|
for {
|
||
|
select {
|
||
|
case event, ok := <-watcher.Events:
|
||
|
if !ok {
|
||
|
l.Warning("watcher events chan closed, terminating")
|
||
|
return
|
||
|
}
|
||
|
if event.Op&fsnotify.Write == fsnotify.Write && event.Name == file {
|
||
|
l.Info("file modification event", "file", file)
|
||
|
onWrite()
|
||
|
}
|
||
|
case err, ok := <-watcher.Errors:
|
||
|
if !ok {
|
||
|
l.Warning("watcher error chan closed, terminating")
|
||
|
return
|
||
|
}
|
||
|
l.Error("file watcher error", "error", err)
|
||
|
}
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
// Watch the directory over the file.
|
||
|
err = watcher.Add(path.Dir(file))
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("could not add file %s to watcher: %w", file, err)
|
||
|
}
|
||
|
return nil
|
||
|
}
|