mirror of
https://github.com/go-task/task.git
synced 2024-12-14 10:52:43 +02:00
99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package task
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/fsnotify/fsnotify"
|
|
"github.com/mattn/go-zglob"
|
|
)
|
|
|
|
// WatchTasks start watching the given tasks
|
|
func WatchTasks(args []string) error {
|
|
log.Printf("task: Started watching for tasks: %s", strings.Join(args, ", "))
|
|
|
|
// run tasks on init
|
|
for _, a := range args {
|
|
if err := RunTask(a); err != nil {
|
|
fmt.Println(err)
|
|
break
|
|
}
|
|
}
|
|
|
|
watcher, err := fsnotify.NewWatcher()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer watcher.Close()
|
|
|
|
go func() {
|
|
for {
|
|
if err := registerWatchedFiles(watcher, args); err != nil {
|
|
log.Printf("Error watching files: %v", err)
|
|
}
|
|
time.Sleep(time.Second * 2)
|
|
}
|
|
}()
|
|
|
|
loop:
|
|
for {
|
|
select {
|
|
case <-watcher.Events:
|
|
for _, a := range args {
|
|
if err := RunTask(a); err != nil {
|
|
fmt.Println(err)
|
|
continue loop
|
|
}
|
|
}
|
|
case err := <-watcher.Errors:
|
|
fmt.Println(err)
|
|
continue loop
|
|
}
|
|
}
|
|
}
|
|
|
|
var watchingFiles map[string]struct{}
|
|
|
|
func registerWatchedFiles(w *fsnotify.Watcher, args []string) error {
|
|
oldWatchingFiles := watchingFiles
|
|
watchingFiles = make(map[string]struct{}, len(oldWatchingFiles))
|
|
|
|
for k := range oldWatchingFiles {
|
|
if err := w.Remove(k); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, a := range args {
|
|
task, ok := Tasks[a]
|
|
if !ok {
|
|
return &taskNotFoundError{a}
|
|
}
|
|
if err := registerWatchedFiles(w, task.Deps); err != nil {
|
|
return err
|
|
}
|
|
for _, s := range task.Sources {
|
|
files, err := zglob.Glob(s)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, f := range files {
|
|
if err := w.Add(f); err != nil {
|
|
return err
|
|
}
|
|
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
|
|
}
|