@@ -19,6 +19,8 @@ import (
1919 "github.com/go-task/task/v3/internal/fingerprint"
2020 "github.com/go-task/task/v3/internal/fsnotifyext"
2121 "github.com/go-task/task/v3/internal/logger"
22+ "github.com/go-task/task/v3/internal/slicesext"
23+ "github.com/go-task/task/v3/taskfile/ast"
2224)
2325
2426const defaultWaitTime = 100 * time .Millisecond
@@ -85,17 +87,22 @@ func (e *Executor) watchTasks(calls ...*Call) error {
8587 for _ , c := range calls {
8688 c := c
8789 go func () {
90+ if ShouldIgnore (event .Name ) {
91+ e .Logger .VerboseErrf (logger .Magenta , "task: event skipped for being an ignored dir: %s\n " , event .Name )
92+ return
93+ }
8894 t , err := e .GetTask (c )
8995 if err != nil {
9096 e .Logger .Errf (logger .Red , "%v\n " , err )
9197 return
9298 }
9399 baseDir := filepathext .SmartJoin (e .Dir , t .Dir )
94- files , err := fingerprint . Globs ( baseDir , t . Sources )
100+ files , err := e . collectSources ( calls )
95101 if err != nil {
96102 e .Logger .Errf (logger .Red , "%v\n " , err )
97103 return
98104 }
105+
99106 if ! event .Has (fsnotify .Remove ) && ! slices .Contains (files , event .Name ) {
100107 relPath , _ := filepath .Rel (baseDir , event .Name )
101108 e .Logger .VerboseErrf (logger .Magenta , "task: skipped for file not in sources: %s\n " , relPath )
@@ -158,69 +165,84 @@ func closeOnInterrupt(w *fsnotify.Watcher) {
158165}
159166
160167func (e * Executor ) registerWatchedDirs (w * fsnotify.Watcher , calls ... * Call ) error {
161- var registerTaskDirs func (* Call ) error
162- registerTaskDirs = func (c * Call ) error {
163- task , err := e .CompiledTask (c )
164- if err != nil {
168+ files , err := e .collectSources (calls )
169+ if err != nil {
170+ return err
171+ }
172+ for _ , f := range files {
173+ d := filepath .Dir (f )
174+ if isSet , ok := e .watchedDirs .Load (d ); ok && isSet {
175+ continue
176+ }
177+ if ShouldIgnore (d ) {
178+ continue
179+ }
180+ if err := w .Add (d ); err != nil {
165181 return err
166182 }
183+ e .watchedDirs .Store (d , true )
184+ relPath , _ := filepath .Rel (e .Dir , d )
185+ e .Logger .VerboseOutf (logger .Green , "task: watching new dir: %v\n " , relPath )
186+ }
187+ return nil
188+ }
167189
168- for _ , d := range task . Deps {
169- if err := registerTaskDirs ( & Call { Task : d . Task , Vars : d . Vars }); err != nil {
170- return err
171- }
172- }
173- for _ , c := range task . Cmds {
174- if c . Task != "" {
175- if err := registerTaskDirs ( & Call { Task : c . Task , Vars : c . Vars }); err != nil {
176- return err
177- }
178- }
190+ var ignorePaths = [] string {
191+ "/.task" ,
192+ "/.git" ,
193+ "/.hg" ,
194+ "/node_modules" ,
195+ }
196+
197+ func ShouldIgnore ( path string ) bool {
198+ for _ , p := range ignorePaths {
199+ if strings . Contains ( path , fmt . Sprintf ( "%s/" , p )) || strings . HasSuffix ( path , p ) {
200+ return true
179201 }
202+ }
203+ return false
204+ }
205+
206+ func (e * Executor ) collectSources (calls []* Call ) ([]string , error ) {
207+ var sources []string
180208
209+ err := e .traverse (calls , func (task * ast.Task ) error {
181210 files , err := fingerprint .Globs (task .Dir , task .Sources )
182211 if err != nil {
183212 return err
184213 }
214+ sources = append (sources , files ... )
215+ return nil
216+ })
185217
186- for _ , f := range files {
187- d := filepath .Dir (f )
188- if isSet , ok := e .watchedDirs .Load (d ); ok && isSet {
189- continue
190- }
191- if ShouldIgnoreFile (d ) {
192- continue
218+ return slicesext .UniqueJoin (sources ), err
219+ }
220+
221+ type traverseFunc func (* ast.Task ) error
222+
223+ func (e * Executor ) traverse (calls []* Call , yield traverseFunc ) error {
224+ for _ , c := range calls {
225+ task , err := e .CompiledTask (c )
226+ if err != nil {
227+ return err
228+ }
229+ for _ , dep := range task .Deps {
230+ if dep .Task != "" {
231+ if err := e .traverse ([]* Call {{Task : dep .Task , Vars : dep .Vars }}, yield ); err != nil {
232+ return err
233+ }
193234 }
194- if err := w .Add (d ); err != nil {
195- return err
235+ }
236+ for _ , cmd := range task .Cmds {
237+ if cmd .Task != "" {
238+ if err := e .traverse ([]* Call {{Task : cmd .Task , Vars : cmd .Vars }}, yield ); err != nil {
239+ return err
240+ }
196241 }
197- e .watchedDirs .Store (d , true )
198- relPath , _ := filepath .Rel (e .Dir , d )
199- w .Events <- fsnotify.Event {Name : f , Op : fsnotify .Create }
200- e .Logger .VerboseOutf (logger .Green , "task: watching new dir: %v\n " , relPath )
201242 }
202- return nil
203- }
204-
205- for _ , c := range calls {
206- if err := registerTaskDirs (c ); err != nil {
243+ if err := yield (task ); err != nil {
207244 return err
208245 }
209246 }
210247 return nil
211248}
212-
213- func ShouldIgnoreFile (path string ) bool {
214- ignorePaths := []string {
215- "/.task" ,
216- "/.git" ,
217- "/.hg" ,
218- "/node_modules" ,
219- }
220- for _ , p := range ignorePaths {
221- if strings .Contains (path , fmt .Sprintf ("%s/" , p )) || strings .HasSuffix (path , p ) {
222- return true
223- }
224- }
225- return false
226- }
0 commit comments