1
0
mirror of https://github.com/go-task/task.git synced 2025-02-03 13:22:11 +02:00

Watch task

This commit is contained in:
Andrey Nering 2017-04-01 16:04:52 -03:00
parent 36614dccf8
commit 72a6727e31
4 changed files with 116 additions and 0 deletions

View File

@ -26,6 +26,7 @@ hello:
pflag.PrintDefaults()
}
pflag.BoolVarP(&task.Force, "force", "f", false, "forces execution even when the task is up-to-date")
pflag.BoolVarP(&task.Watch, "watch", "w", false, "enables watch of the given task")
pflag.Parse()
task.Run()
}

View File

@ -36,3 +36,11 @@ type cyclicDepError struct {
func (err *cyclicDepError) Error() string {
return fmt.Sprintf(`task: Cyclic dependency of task "%s" detected`, err.taskName)
}
type cantWatchNoSourcesError struct {
taskName string
}
func (err *cantWatchNoSourcesError) Error() string {
return fmt.Sprintf(`task: Can't watch task "%s" because it has no specified sources`, err.taskName)
}

View File

@ -18,6 +18,8 @@ var (
// Force (--force or -f flag) forces a task to run even when it's up-to-date
Force bool
// Watch (--watch or -w flag) enables watch of a task
Watch bool
// Tasks constains the tasks parsed from Taskfile
Tasks = make(map[string]*Task)
@ -66,6 +68,13 @@ func Run() {
}
}
if Watch {
if err := WatchTasks(args); err != nil {
log.Fatal(err)
}
return
}
for _, a := range args {
if err = RunTask(a); err != nil {
log.Fatal(err)

98
watch.go Normal file
View File

@ -0,0 +1,98 @@
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
}