1
0
mirror of https://github.com/go-task/task.git synced 2025-08-10 22:42:19 +02:00

fix(watcher): fix some v3.43.x regressions (#2271)

This commit is contained in:
Andrey Nering
2025-06-08 19:44:08 -03:00
committed by GitHub
parent 9cc2d65091
commit 7782bc92ae
2 changed files with 85 additions and 62 deletions

View File

@@ -19,6 +19,8 @@ import (
"github.com/go-task/task/v3/internal/fingerprint" "github.com/go-task/task/v3/internal/fingerprint"
"github.com/go-task/task/v3/internal/fsnotifyext" "github.com/go-task/task/v3/internal/fsnotifyext"
"github.com/go-task/task/v3/internal/logger" "github.com/go-task/task/v3/internal/logger"
"github.com/go-task/task/v3/internal/slicesext"
"github.com/go-task/task/v3/taskfile/ast"
) )
const defaultWaitTime = 100 * time.Millisecond const defaultWaitTime = 100 * time.Millisecond
@@ -85,17 +87,22 @@ func (e *Executor) watchTasks(calls ...*Call) error {
for _, c := range calls { for _, c := range calls {
c := c c := c
go func() { go func() {
if ShouldIgnore(event.Name) {
e.Logger.VerboseErrf(logger.Magenta, "task: event skipped for being an ignored dir: %s\n", event.Name)
return
}
t, err := e.GetTask(c) t, err := e.GetTask(c)
if err != nil { if err != nil {
e.Logger.Errf(logger.Red, "%v\n", err) e.Logger.Errf(logger.Red, "%v\n", err)
return return
} }
baseDir := filepathext.SmartJoin(e.Dir, t.Dir) baseDir := filepathext.SmartJoin(e.Dir, t.Dir)
files, err := fingerprint.Globs(baseDir, t.Sources) files, err := e.collectSources(calls)
if err != nil { if err != nil {
e.Logger.Errf(logger.Red, "%v\n", err) e.Logger.Errf(logger.Red, "%v\n", err)
return return
} }
if !event.Has(fsnotify.Remove) && !slices.Contains(files, event.Name) { if !event.Has(fsnotify.Remove) && !slices.Contains(files, event.Name) {
relPath, _ := filepath.Rel(baseDir, event.Name) relPath, _ := filepath.Rel(baseDir, event.Name)
e.Logger.VerboseErrf(logger.Magenta, "task: skipped for file not in sources: %s\n", relPath) e.Logger.VerboseErrf(logger.Magenta, "task: skipped for file not in sources: %s\n", relPath)
@@ -158,37 +165,16 @@ func closeOnInterrupt(w *fsnotify.Watcher) {
} }
func (e *Executor) registerWatchedDirs(w *fsnotify.Watcher, calls ...*Call) error { func (e *Executor) registerWatchedDirs(w *fsnotify.Watcher, calls ...*Call) error {
var registerTaskDirs func(*Call) error files, err := e.collectSources(calls)
registerTaskDirs = func(c *Call) error {
task, err := e.CompiledTask(c)
if err != nil { if err != nil {
return err return err
} }
for _, d := range task.Deps {
if err := registerTaskDirs(&Call{Task: d.Task, Vars: d.Vars}); err != nil {
return err
}
}
for _, c := range task.Cmds {
if c.Task != "" {
if err := registerTaskDirs(&Call{Task: c.Task, Vars: c.Vars}); err != nil {
return err
}
}
}
files, err := fingerprint.Globs(task.Dir, task.Sources)
if err != nil {
return err
}
for _, f := range files { for _, f := range files {
d := filepath.Dir(f) d := filepath.Dir(f)
if isSet, ok := e.watchedDirs.Load(d); ok && isSet { if isSet, ok := e.watchedDirs.Load(d); ok && isSet {
continue continue
} }
if ShouldIgnoreFile(d) { if ShouldIgnore(d) {
continue continue
} }
if err := w.Add(d); err != nil { if err := w.Add(d); err != nil {
@@ -196,27 +182,19 @@ func (e *Executor) registerWatchedDirs(w *fsnotify.Watcher, calls ...*Call) erro
} }
e.watchedDirs.Store(d, true) e.watchedDirs.Store(d, true)
relPath, _ := filepath.Rel(e.Dir, d) relPath, _ := filepath.Rel(e.Dir, d)
w.Events <- fsnotify.Event{Name: f, Op: fsnotify.Create}
e.Logger.VerboseOutf(logger.Green, "task: watching new dir: %v\n", relPath) e.Logger.VerboseOutf(logger.Green, "task: watching new dir: %v\n", relPath)
} }
return nil return nil
} }
for _, c := range calls { var ignorePaths = []string{
if err := registerTaskDirs(c); err != nil {
return err
}
}
return nil
}
func ShouldIgnoreFile(path string) bool {
ignorePaths := []string{
"/.task", "/.task",
"/.git", "/.git",
"/.hg", "/.hg",
"/node_modules", "/node_modules",
} }
func ShouldIgnore(path string) bool {
for _, p := range ignorePaths { for _, p := range ignorePaths {
if strings.Contains(path, fmt.Sprintf("%s/", p)) || strings.HasSuffix(path, p) { if strings.Contains(path, fmt.Sprintf("%s/", p)) || strings.HasSuffix(path, p) {
return true return true
@@ -224,3 +202,47 @@ func ShouldIgnoreFile(path string) bool {
} }
return false return false
} }
func (e *Executor) collectSources(calls []*Call) ([]string, error) {
var sources []string
err := e.traverse(calls, func(task *ast.Task) error {
files, err := fingerprint.Globs(task.Dir, task.Sources)
if err != nil {
return err
}
sources = append(sources, files...)
return nil
})
return slicesext.UniqueJoin(sources), err
}
type traverseFunc func(*ast.Task) error
func (e *Executor) traverse(calls []*Call, yield traverseFunc) error {
for _, c := range calls {
task, err := e.CompiledTask(c)
if err != nil {
return err
}
for _, dep := range task.Deps {
if dep.Task != "" {
if err := e.traverse([]*Call{{Task: dep.Task, Vars: dep.Vars}}, yield); err != nil {
return err
}
}
}
for _, cmd := range task.Cmds {
if cmd.Task != "" {
if err := e.traverse([]*Call{{Task: cmd.Task, Vars: cmd.Vars}}, yield); err != nil {
return err
}
}
}
if err := yield(task); err != nil {
return err
}
}
return nil
}

View File

@@ -31,16 +31,17 @@ task: Started watching for tasks: default
task: [default] echo "Task running!" task: [default] echo "Task running!"
Task running! Task running!
task: task "default" finished running task: task "default" finished running
task: Task "default" is up to date task: [default] echo "Task running!"
Task running!
task: task "default" finished running task: task "default" finished running
`) `)
var buff bytes.Buffer var buff bytes.Buffer
e := task.NewExecutor( e := task.NewExecutor(
task.ExecutorWithDir(dir), task.WithDir(dir),
task.ExecutorWithStdout(&buff), task.WithStdout(&buff),
task.ExecutorWithStderr(&buff), task.WithStderr(&buff),
task.ExecutorWithWatch(true), task.WithWatch(true),
) )
require.NoError(t, e.Setup()) require.NoError(t, e.Setup())
@@ -71,16 +72,16 @@ task: task "default" finished running
} }
}() }()
time.Sleep(10 * time.Millisecond) time.Sleep(200 * time.Millisecond)
err = os.WriteFile(filePath, []byte("test updated"), 0o644) err = os.WriteFile(filePath, []byte("test updated"), 0o644)
require.NoError(t, err) require.NoError(t, err)
time.Sleep(150 * time.Millisecond) time.Sleep(200 * time.Millisecond)
cancel() cancel()
assert.Equal(t, expectedOutput, strings.TrimSpace(buff.String())) assert.Equal(t, expectedOutput, strings.TrimSpace(buff.String()))
} }
func TestShouldIgnoreFile(t *testing.T) { func TestShouldIgnore(t *testing.T) {
t.Parallel() t.Parallel()
tt := []struct { tt := []struct {
@@ -95,7 +96,7 @@ func TestShouldIgnoreFile(t *testing.T) {
ct := ct ct := ct
t.Run(fmt.Sprintf("ignore - %d", k), func(t *testing.T) { t.Run(fmt.Sprintf("ignore - %d", k), func(t *testing.T) {
t.Parallel() t.Parallel()
require.Equal(t, task.ShouldIgnoreFile(ct.path), ct.expect) require.Equal(t, task.ShouldIgnore(ct.path), ct.expect)
}) })
} }
} }