1
0
mirror of https://github.com/go-task/task.git synced 2024-12-04 10:24:45 +02:00

Issue 813. Made watch interval configurable through global setting in Taskfile and through CLI arg.

Separated Taskfile param and Arg flag
This commit is contained in:
ilewin 2022-09-08 19:22:44 +02:00
parent 160b788198
commit 1c44d8049a
7 changed files with 122 additions and 1 deletions

View File

@ -73,6 +73,7 @@ func main() {
entrypoint string
output taskfile.Output
color bool
interval string
)
pflag.BoolVar(&versionFlag, "version", false, "show Task version")
@ -96,6 +97,7 @@ func main() {
pflag.StringVar(&output.Group.End, "output-group-end", "", "message template to print after a task's grouped output")
pflag.BoolVarP(&color, "color", "c", true, "colored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable")
pflag.IntVarP(&concurrency, "concurrency", "C", 0, "limit number tasks to run concurrently")
pflag.StringVarP(&interval, "interval", "I", "5s", "interval to watch for changes")
pflag.Parse()
if versionFlag {
@ -151,6 +153,7 @@ func main() {
Parallel: parallel,
Color: color,
Concurrency: concurrency,
Interval: interval,
Stdin: os.Stdin,
Stdout: os.Stdout,
@ -206,6 +209,10 @@ func main() {
e.InterceptInterruptSignals()
}
if e.Interval == "" {
e.Interval = strings.TrimSpace(interval)
}
ctx := context.Background()
if status {

View File

@ -41,6 +41,7 @@ type Executor struct {
Parallel bool
Color bool
Concurrency int
Interval string
Stdin io.Reader
Stdout io.Writer

View File

@ -10,6 +10,7 @@ import (
"runtime"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
@ -1400,3 +1401,63 @@ func TestEvaluateSymlinksInPaths(t *testing.T) {
err = os.RemoveAll(dir + "/.task")
assert.NoError(t, err)
}
func TestFileWatcherInterval(t *testing.T) {
const dir = "testdata/watcher_interval"
expectedOutput := strings.TrimSpace(`
task: Started watching for tasks: default
task: [default] echo "Hello, World!"
Hello, World!
task: [default] echo "Hello, World!"
Hello, World!
`)
var buff bytes.Buffer
e := &task.Executor{
Dir: dir,
Stdout: &buff,
Stderr: &buff,
Watch: true,
}
assert.NoError(t, e.Setup())
buff.Reset()
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
err := os.MkdirAll(dir+"/src", 0755)
assert.NoError(t, err)
err = os.WriteFile(dir+"/src/a", []byte("test"), 0644)
if err != nil {
t.Fatal(err)
}
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
default:
err := e.Run(ctx, taskfile.Call{Task: "default"})
if err != nil {
return
}
}
}
}(ctx)
time.Sleep(10 * time.Millisecond)
err = os.WriteFile(dir+"/src/a", []byte("test updated"), 0644)
if err != nil {
t.Fatal(err)
}
time.Sleep(70 * time.Millisecond)
cancel()
assert.Equal(t, expectedOutput, strings.TrimSpace(buff.String()))
buff.Reset()
err = os.RemoveAll(dir + "/.task")
assert.NoError(t, err)
}

View File

@ -18,6 +18,7 @@ type Taskfile struct {
Silent bool
Dotenv []string
Run string
Interval string
}
// UnmarshalYAML implements yaml.Unmarshaler interface
@ -34,10 +35,13 @@ func (tf *Taskfile) UnmarshalYAML(unmarshal func(interface{}) error) error {
Silent bool
Dotenv []string
Run string
Interval string
}
if err := unmarshal(&taskfile); err != nil {
return err
}
tf.Version = taskfile.Version
tf.Expansions = taskfile.Expansions
tf.Output = taskfile.Output
@ -49,6 +53,8 @@ func (tf *Taskfile) UnmarshalYAML(unmarshal func(interface{}) error) error {
tf.Silent = taskfile.Silent
tf.Dotenv = taskfile.Dotenv
tf.Run = taskfile.Run
tf.Interval = taskfile.Interval
if tf.Expansions <= 0 {
tf.Expansions = 2
}

1
testdata/watcher_interval/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
src/*

16
testdata/watcher_interval/Taskfile.yaml vendored Normal file
View File

@ -0,0 +1,16 @@
# https://taskfile.dev
version: '3'
vars:
GREETING: Hello, World!
interval: "50ms"
tasks:
default:
sources:
- "src/*"
cmds:
- echo "{{.GREETING}}"
silent: false

View File

@ -16,7 +16,7 @@ import (
"github.com/radovskyb/watcher"
)
const watchInterval = 5 * time.Second
const defaultWatchInterval = 5 * time.Second
// watchTasks start watching the given tasks
func (e *Executor) watchTasks(calls ...taskfile.Call) error {
@ -24,6 +24,7 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error {
for i, c := range calls {
tasks[i] = c.Task
}
e.Logger.Errf(logger.Green, "task: Started watching for tasks: %s", strings.Join(tasks, ", "))
ctx, cancel := context.WithCancel(context.Background())
@ -36,6 +37,26 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error {
}()
}
var watchIntervalString string
if e.Taskfile.Interval != "" {
watchIntervalString = e.Taskfile.Interval
} else if e.Interval != "" {
watchIntervalString = e.Interval
}
watchInterval := defaultWatchInterval
if watchIntervalString != "" {
var err error
watchInterval, err = parsedWatchInterval(watchIntervalString)
if err != nil {
e.Logger.Errf(logger.Red, "%v", err)
}
}
e.Logger.VerboseOutf(logger.Green, "task: Watching for changes every %v", watchInterval)
w := watcher.New()
defer w.Close()
w.SetMaxEvents(1)
@ -163,3 +184,11 @@ func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...taskfile.Ca
func shouldIgnoreFile(path string) bool {
return strings.Contains(path, "/.git") || strings.Contains(path, "/.task") || strings.Contains(path, "/node_modules")
}
func parsedWatchInterval(watchInterval string) (time.Duration, error) {
v, err := time.ParseDuration(watchInterval)
if err != nil {
return 0, fmt.Errorf(`task: Could not parse watch interval "%s": %v`, watchInterval, err)
}
return v, nil
}