@@ -19,6 +19,8 @@ import (
19
19
"github.com/go-task/task/v3/internal/fingerprint"
20
20
"github.com/go-task/task/v3/internal/fsnotifyext"
21
21
"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"
22
24
)
23
25
24
26
const defaultWaitTime = 100 * time .Millisecond
@@ -91,11 +93,12 @@ func (e *Executor) watchTasks(calls ...*Call) error {
91
93
return
92
94
}
93
95
baseDir := filepathext .SmartJoin (e .Dir , t .Dir )
94
- files , err := fingerprint . Globs ( baseDir , t . Sources )
96
+ files , err := e . collectSources ( calls )
95
97
if err != nil {
96
98
e .Logger .Errf (logger .Red , "%v\n " , err )
97
99
return
98
100
}
101
+
99
102
if ! event .Has (fsnotify .Remove ) && ! slices .Contains (files , event .Name ) {
100
103
relPath , _ := filepath .Rel (baseDir , event .Name )
101
104
e .Logger .VerboseErrf (logger .Magenta , "task: skipped for file not in sources: %s\n " , relPath )
@@ -158,54 +161,24 @@ func closeOnInterrupt(w *fsnotify.Watcher) {
158
161
}
159
162
160
163
func (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 {
165
- return err
166
- }
167
-
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
- }
179
- }
180
-
181
- files , err := fingerprint .Globs (task .Dir , task .Sources )
182
- if err != nil {
183
- return err
164
+ files , err := e .collectSources (calls )
165
+ if err != nil {
166
+ return err
167
+ }
168
+ for _ , f := range files {
169
+ d := filepath .Dir (f )
170
+ if isSet , ok := e .watchedDirs .Load (d ); ok && isSet {
171
+ continue
184
172
}
185
-
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
193
- }
194
- if err := w .Add (d ); err != nil {
195
- return err
196
- }
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 )
173
+ if ShouldIgnoreFile (d ) {
174
+ continue
201
175
}
202
- return nil
203
- }
204
-
205
- for _ , c := range calls {
206
- if err := registerTaskDirs (c ); err != nil {
176
+ if err := w .Add (d ); err != nil {
207
177
return err
208
178
}
179
+ e .watchedDirs .Store (d , true )
180
+ relPath , _ := filepath .Rel (e .Dir , d )
181
+ e .Logger .VerboseOutf (logger .Green , "task: watching new dir: %v\n " , relPath )
209
182
}
210
183
return nil
211
184
}
@@ -224,3 +197,47 @@ func ShouldIgnoreFile(path string) bool {
224
197
}
225
198
return false
226
199
}
200
+
201
+ func (e * Executor ) collectSources (calls []* Call ) ([]string , error ) {
202
+ var sources []string
203
+
204
+ err := e .traverse (calls , func (task * ast.Task ) error {
205
+ files , err := fingerprint .Globs (task .Dir , task .Sources )
206
+ if err != nil {
207
+ return err
208
+ }
209
+ sources = append (sources , files ... )
210
+ return nil
211
+ })
212
+
213
+ return slicesext .UniqueJoin (sources ), err
214
+ }
215
+
216
+ type traverseFunc func (* ast.Task ) error
217
+
218
+ func (e * Executor ) traverse (calls []* Call , yield traverseFunc ) error {
219
+ for _ , c := range calls {
220
+ task , err := e .CompiledTask (c )
221
+ if err != nil {
222
+ return err
223
+ }
224
+ for _ , dep := range task .Deps {
225
+ if dep .Task != "" {
226
+ if err := e .traverse ([]* Call {{Task : dep .Task , Vars : dep .Vars }}, yield ); err != nil {
227
+ return err
228
+ }
229
+ }
230
+ }
231
+ for _ , cmd := range task .Cmds {
232
+ if cmd .Task != "" {
233
+ if err := e .traverse ([]* Call {{Task : cmd .Task , Vars : cmd .Vars }}, yield ); err != nil {
234
+ return err
235
+ }
236
+ }
237
+ }
238
+ if err := yield (task ); err != nil {
239
+ return err
240
+ }
241
+ }
242
+ return nil
243
+ }
0 commit comments