git-webhook-ci/internal/watcher/watcher.go

86 lines
1.8 KiB
Go

package watcher
import (
"errors"
"log"
"gitea.urkob.com/urko/git-webhook-ci/pkg"
"github.com/fsnotify/fsnotify"
)
type watcher struct {
fswatcher *fsnotify.Watcher
deploy pkg.DeployFunc
}
type notifier struct{}
func (n *notifier) NewWatcher() (*fsnotify.Watcher, error) {
return fsnotify.NewWatcher()
}
func NewNotifier() *notifier {
return &notifier{}
}
var (
errEventsClosedChan = errors.New("events is closed")
errErrorsClosedChan = errors.New("errors is closed")
)
func NewWatcher(notifier pkg.NotifyIface, deploy pkg.DeployFunc) *watcher {
wt, err := notifier.NewWatcher()
if err != nil {
log.Printf("fsnotify.NewWatcher: %s\n", err)
return nil
}
return &watcher{
fswatcher: wt,
deploy: deploy,
}
}
func (w *watcher) Monitor(path string) error {
return w.fswatcher.Add(path)
}
// Start listening for events.
func (w *watcher) Listen(binaryPath, scriptPath string, outputErr chan<- error) {
go func(events chan fsnotify.Event, errChan chan error, outputErr chan<- error) {
for {
select {
case event, ok := <-events:
if !ok {
log.Println(errEventsClosedChan)
outputErr <- errEventsClosedChan
return
}
if !event.Has(fsnotify.Write) {
log.Printf("is not Write: %s\n", event.Name)
continue
}
log.Printf("event: %s | op: %s \n", event.Name, event.Op)
if err := w.deploy(binaryPath, scriptPath); err != nil {
log.Printf("deploy: %s\n", err)
outputErr <- err
continue
}
case err, ok := <-errChan:
if !ok {
log.Println(errErrorsClosedChan)
outputErr <- errErrorsClosedChan
return
}
log.Printf("<-errors: %s\n", err)
outputErr <- err
}
}
}(w.fswatcher.Events, w.fswatcher.Errors, outputErr)
}
func (w *watcher) Close() error {
return w.fswatcher.Close()
}