mirror of
https://github.com/go-task/task.git
synced 2025-07-17 01:43:07 +02:00
watch: switch to watcher as waych lib and few fixes
watcher whould be more consistent across differente OSes
This commit is contained in:
3
task.go
3
task.go
@ -36,8 +36,7 @@ type Executor struct {
|
|||||||
Stdout io.Writer
|
Stdout io.Writer
|
||||||
Stderr io.Writer
|
Stderr io.Writer
|
||||||
|
|
||||||
taskvars Vars
|
taskvars Vars
|
||||||
watchingFiles map[string]struct{}
|
|
||||||
|
|
||||||
taskCallCount map[string]*int32
|
taskCallCount map[string]*int32
|
||||||
|
|
||||||
|
111
watch.go
111
watch.go
@ -5,8 +5,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fsnotify/fsnotify"
|
|
||||||
"github.com/mattn/go-zglob"
|
"github.com/mattn/go-zglob"
|
||||||
|
"github.com/radovskyb/watcher"
|
||||||
)
|
)
|
||||||
|
|
||||||
// watchTasks start watching the given tasks
|
// watchTasks start watching the given tasks
|
||||||
@ -31,81 +31,100 @@ func (e *Executor) watchTasks(args ...string) error {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
watcher, err := fsnotify.NewWatcher()
|
w := watcher.New()
|
||||||
if err != nil {
|
defer w.Close()
|
||||||
return err
|
w.SetMaxEvents(1)
|
||||||
}
|
|
||||||
defer watcher.Close()
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
if err := e.registerWatchedFiles(watcher, args); err != nil {
|
select {
|
||||||
e.printfln("Error watching files: %v", err)
|
case event := <-w.Event:
|
||||||
|
e.verbosePrintfln("task: received watch event: %v", event)
|
||||||
|
|
||||||
|
cancel()
|
||||||
|
ctx, cancel = context.WithCancel(context.Background())
|
||||||
|
for _, a := range args {
|
||||||
|
a := a
|
||||||
|
go func() {
|
||||||
|
if err := e.RunTask(ctx, Call{Task: a}); err != nil && !isCtxErr(err) {
|
||||||
|
e.println(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
case err := <-w.Error:
|
||||||
|
switch err {
|
||||||
|
case watcher.ErrWatchedFileDeleted:
|
||||||
|
go func() {
|
||||||
|
w.TriggerEvent(watcher.Remove, nil)
|
||||||
|
}()
|
||||||
|
default:
|
||||||
|
e.println(err)
|
||||||
|
}
|
||||||
|
case <-w.Closed:
|
||||||
|
return
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second * 2)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for {
|
go func() {
|
||||||
select {
|
// re-register each second because we can have new files
|
||||||
case <-watcher.Events:
|
for {
|
||||||
cancel()
|
if err := e.registerWatchedFiles(w, args); err != nil {
|
||||||
ctx, cancel = context.WithCancel(context.Background())
|
e.println(err)
|
||||||
for _, a := range args {
|
|
||||||
a := a
|
|
||||||
go func() {
|
|
||||||
if err := e.RunTask(ctx, Call{Task: a}); err != nil && !isCtxErr(err) {
|
|
||||||
e.println(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
case err := <-watcher.Errors:
|
time.Sleep(time.Second)
|
||||||
e.println(err)
|
|
||||||
}
|
}
|
||||||
}
|
}()
|
||||||
|
|
||||||
|
return w.Start(time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) registerWatchedFiles(w *fsnotify.Watcher, args []string) error {
|
func (e *Executor) registerWatchedFiles(w *watcher.Watcher, args []string) error {
|
||||||
oldWatchingFiles := e.watchingFiles
|
oldWatchedFiles := make(map[string]struct{})
|
||||||
e.watchingFiles = make(map[string]struct{}, len(oldWatchingFiles))
|
for f := range w.WatchedFiles() {
|
||||||
|
oldWatchedFiles[f] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
for k := range oldWatchingFiles {
|
for f := range oldWatchedFiles {
|
||||||
if err := w.Remove(k); err != nil {
|
if err := w.Remove(f); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, a := range args {
|
var registerTaskFiles func(string) error
|
||||||
task, ok := e.Tasks[a]
|
registerTaskFiles = func(t string) error {
|
||||||
|
task, ok := e.Tasks[t]
|
||||||
if !ok {
|
if !ok {
|
||||||
return &taskNotFoundError{a}
|
return &taskNotFoundError{t}
|
||||||
}
|
}
|
||||||
deps := make([]string, len(task.Deps))
|
|
||||||
for i, d := range task.Deps {
|
for _, d := range task.Deps {
|
||||||
deps[i] = d.Task
|
if err := registerTaskFiles(d.Task); err != nil {
|
||||||
}
|
return err
|
||||||
if err := e.registerWatchedFiles(w, deps); err != nil {
|
}
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range task.Sources {
|
for _, s := range task.Sources {
|
||||||
files, err := zglob.Glob(s)
|
files, err := zglob.Glob(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
|
if _, ok := oldWatchedFiles[f]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if err := w.Add(f); err != nil {
|
if err := w.Add(f); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.watchingFiles[f] = struct{}{}
|
|
||||||
|
|
||||||
// run if is new file
|
|
||||||
if oldWatchingFiles != nil {
|
|
||||||
if _, ok := oldWatchingFiles[f]; !ok {
|
|
||||||
w.Events <- fsnotify.Event{Name: f, Op: fsnotify.Create}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range args {
|
||||||
|
if err := registerTaskFiles(a); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user