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.PrintDefaults()
|
||||||
}
|
}
|
||||||
pflag.BoolVarP(&task.Force, "force", "f", false, "forces execution even when the task is up-to-date")
|
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()
|
pflag.Parse()
|
||||||
task.Run()
|
task.Run()
|
||||||
}
|
}
|
||||||
|
@ -36,3 +36,11 @@ type cyclicDepError struct {
|
|||||||
func (err *cyclicDepError) Error() string {
|
func (err *cyclicDepError) Error() string {
|
||||||
return fmt.Sprintf(`task: Cyclic dependency of task "%s" detected`, err.taskName)
|
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 (--force or -f flag) forces a task to run even when it's up-to-date
|
||||||
Force bool
|
Force bool
|
||||||
|
// Watch (--watch or -w flag) enables watch of a task
|
||||||
|
Watch bool
|
||||||
|
|
||||||
// Tasks constains the tasks parsed from Taskfile
|
// Tasks constains the tasks parsed from Taskfile
|
||||||
Tasks = make(map[string]*Task)
|
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 {
|
for _, a := range args {
|
||||||
if err = RunTask(a); err != nil {
|
if err = RunTask(a); err != nil {
|
||||||
log.Fatal(err)
|
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