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:
parent
36614dccf8
commit
72a6727e31
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
9
task.go
9
task.go
@ -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
98
watch.go
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user