88 "os/exec"
99 "path/filepath"
1010 "strings"
11+ "sync"
1112 "time"
1213
1314 "github.com/alecthomas/chroma/v2/quick"
@@ -17,6 +18,7 @@ import (
1718 "github.com/nxtcoder17/fwatcher/pkg/watcher"
1819 "github.com/nxtcoder17/runfile/errors"
1920 fn "github.com/nxtcoder17/runfile/functions"
21+ "github.com/nxtcoder17/runfile/logging"
2022 "github.com/nxtcoder17/runfile/parser"
2123 "github.com/nxtcoder17/runfile/types"
2224)
@@ -53,45 +55,27 @@ func isTTY() bool {
5355 return ((stdout .Mode () & os .ModeCharDevice ) == os .ModeCharDevice ) && ((stderr .Mode () & os .ModeCharDevice ) == os .ModeCharDevice )
5456}
5557
56- func runTask (ctx Context , prf * types.ParsedRunfile , args runTaskArgs ) error {
57- runfilePath := prf .Metadata .RunfilePath
58- task := prf .Tasks [args .taskName ]
59-
60- if task .Metadata .RunfilePath != nil {
61- runfilePath = * task .Metadata .RunfilePath
62- }
63-
64- trail := append (args .taskTrail , args .taskName )
65-
66- logger := ctx .With ("task" , args .taskName , "runfile" , runfilePath )
67- logger .Debug ("running task" )
68-
69- task , ok := prf .Tasks [args .taskName ]
70- if ! ok {
71- return errors .ErrTaskNotFound
72- }
73-
74- task .Name = args .taskName
75-
76- pt , err := parser .ParseTask (ctx , prf , task )
77- if err != nil {
78- return errors .WithErr (err )
79- }
80-
58+ func runCommand (ctx Context , prf * types.ParsedRunfile , pt * types.ParsedTask , args runTaskArgs ) error {
8159 for _ , command := range pt .Commands {
82- logger .Debug ("running command task" , "command.run" , command .Run , "parent.task" , args .taskName )
60+ ctx .Debug ("running command task" , "command.run" , command .Run , "parent.task" , args .taskName )
8361
8462 if command .If != nil && ! * command .If {
85- logger .Debug ("skipping execution for failed `if`" , "command" , command .Run )
63+ ctx .Debug ("skipping execution for failed `if`" , "command" , command .Run )
8664 continue
8765 }
8866
8967 if command .Run != "" {
90- if err := runTask (ctx , prf , runTaskArgs {
91- taskTrail : trail ,
92- taskName : command .Run ,
93- envOverrides : pt .Env ,
94- }); err != nil {
68+ rt , ok := prf .Tasks [command .Run ]
69+ if ! ok {
70+ return fmt .Errorf ("invalid run target" )
71+ }
72+
73+ rtp , err := parser .ParseTask (ctx , prf , rt )
74+ if err != nil {
75+ return errors .WithErr (err ).KV ("env-vars" , prf .Env )
76+ }
77+
78+ if err := runCommand (ctx , prf , rtp , args ); err != nil {
9579 return errors .WithErr (err ).KV ("env-vars" , prf .Env )
9680 }
9781 continue
@@ -172,8 +156,14 @@ func runTask(ctx Context, prf *types.ParsedRunfile, args runTaskArgs) error {
172156 fmt .Printf ("%s\n " , s .Render (padString (hlCode .String (), args .taskName )))
173157 }
174158
159+ logger2 := logging .New (logging.Options {
160+ Prefix : "[runfile]" ,
161+ Writer : os .Stderr ,
162+ SlogKeyAsPrefix : "task" ,
163+ })
164+
175165 ex := executor .NewExecutor (executor.ExecutorArgs {
176- Logger : logger ,
166+ Logger : logger2 ,
177167 IsInteractive : pt .Interactive ,
178168 Command : func (c context.Context ) * exec.Cmd {
179169 return CreateCommand (c , CmdArgs {
@@ -188,47 +178,144 @@ func runTask(ctx Context, prf *types.ParsedRunfile, args runTaskArgs) error {
188178 },
189179 })
190180
191- if task .Watch .Enable {
192- watch , err := watcher .NewWatcher (ctx , watcher.WatcherArgs {
193- Logger : logger ,
194- WatchDirs : append (task .Watch .Dirs , pt .WorkingDir ),
195- OnlySuffixes : pt .Watch .OnlySuffixes ,
196- IgnoreSuffixes : pt .Watch .IgnoreSuffixes ,
197- ExcludeDirs : pt .Watch .ExcludeDirs ,
198- UseDefaultIgnoreList : true ,
199- })
181+ // if task.Watch != nil && (task.Watch.Enable == nil || *task.Watch.Enable) {
182+ // watch, err := watcher.NewWatcher(ctx, watcher.WatcherArgs{
183+ // Logger: logger,
184+ // WatchDirs: append(task.Watch.Dirs, pt.WorkingDir),
185+ // OnlySuffixes: pt.Watch.OnlySuffixes,
186+ // IgnoreSuffixes: pt.Watch.IgnoreSuffixes,
187+ // ExcludeDirs: pt.Watch.ExcludeDirs,
188+ // UseDefaultIgnoreList: true,
189+ // // CooldownDuration: fn.New(1 * time.Second),
190+ // })
191+ // if err != nil {
192+ // return errors.WithErr(err)
193+ // }
194+ //
195+ // go ex.Exec()
196+ //
197+ // go func() {
198+ // <-ctx.Done()
199+ // logger.Debug("fwatcher is closing ...")
200+ // watch.Close()
201+ // <-time.After(200 * time.Millisecond)
202+ // logger.Info("CLOSING..................")
203+ // os.Exit(0)
204+ // }()
205+ //
206+ // watch.WatchEvents(func(event watcher.Event, fp string) error {
207+ // relPath, err := filepath.Rel(fn.Must(os.Getwd()), fp)
208+ // if err != nil {
209+ // return err
210+ // }
211+ // logger.Info(fmt.Sprintf("[RELOADING] due changes in %s", relPath))
212+ // ex.Kill()
213+ // select {
214+ // case <-time.After(100 * time.Millisecond):
215+ // go ex.Exec()
216+ // return nil
217+ // case <-ctx.Done():
218+ // logger.Info("close signal received")
219+ // watch.Close()
220+ // return nil
221+ // }
222+ // })
223+ //
224+ // return nil
225+ // }
226+
227+ if err := ex .Exec (); err != nil {
228+ return errors .ErrTaskFailed .Wrap (err ).KV ("task" , args .taskName )
229+ }
230+ }
231+
232+ return nil
233+ }
234+
235+ func runTask (ctx Context , prf * types.ParsedRunfile , args runTaskArgs ) error {
236+ runfilePath := prf .Metadata .RunfilePath
237+ task := prf .Tasks [args .taskName ]
238+
239+ if task .Metadata .RunfilePath != nil {
240+ runfilePath = * task .Metadata .RunfilePath
241+ }
242+
243+ args .taskTrail = append (args .taskTrail , args .taskName )
244+
245+ logger := ctx .With ("task" , args .taskName , "runfile" , runfilePath )
246+ logger .Debug ("running task" )
247+
248+ task , ok := prf .Tasks [args .taskName ]
249+ if ! ok {
250+ return errors .ErrTaskNotFound
251+ }
252+
253+ task .Name = args .taskName
254+
255+ pt , err := parser .ParseTask (ctx , prf , task )
256+ if err != nil {
257+ return errors .WithErr (err )
258+ }
259+
260+ nctx , cf := context .WithCancel (ctx )
261+ defer cf ()
262+
263+ var wg sync.WaitGroup
264+
265+ wg .Add (1 )
266+ go func () {
267+ defer wg .Done ()
268+ runCommand (NewContext (nctx , ctx .Logger ), prf , pt , args )
269+ }()
270+
271+ if pt .Watch != nil && (pt .Watch .Enable == nil || * pt .Watch .Enable ) {
272+ watch , err := watcher .NewWatcher (ctx , watcher.WatcherArgs {
273+ Logger : logger ,
274+ WatchDirs : append (task .Watch .Dirs , pt .WorkingDir ),
275+ OnlySuffixes : pt .Watch .OnlySuffixes ,
276+ IgnoreSuffixes : pt .Watch .IgnoreSuffixes ,
277+ ExcludeDirs : pt .Watch .ExcludeDirs ,
278+ UseDefaultIgnoreList : true ,
279+ // CooldownDuration: fn.New(1 * time.Second),
280+ })
281+ if err != nil {
282+ return errors .WithErr (err )
283+ }
284+
285+ go func () {
286+ <- ctx .Done ()
287+ logger .Debug ("fwatcher is closing ..." )
288+ watch .Close ()
289+ <- time .After (200 * time .Millisecond )
290+ logger .Info ("CLOSING.................." )
291+ os .Exit (0 )
292+ }()
293+
294+ watch .WatchEvents (func (event watcher.Event , fp string ) error {
295+ relPath , err := filepath .Rel (fn .Must (os .Getwd ()), fp )
200296 if err != nil {
201- return errors . WithErr ( err )
297+ return err
202298 }
299+ logger .Info (fmt .Sprintf ("[RELOADING] due changes in %s" , relPath ))
300+ select {
301+ case <- time .After (100 * time .Millisecond ):
302+ cf ()
203303
204- go ex .Exec ()
205-
206- go func () {
207- <- ctx .Done ()
208- logger .Info ("fwatcher is closing ..." )
209- <- time .After (200 * time .Millisecond )
210- os .Exit (0 )
211- }()
212-
213- watch .WatchEvents (func (event watcher.Event , fp string ) error {
214- relPath , err := filepath .Rel (fn .Must (os .Getwd ()), fp )
215- if err != nil {
216- return err
217- }
218- logger .Info (fmt .Sprintf ("[RELOADING] due changes in %s" , relPath ))
219- ex .Kill ()
220- <- time .After (100 * time .Millisecond )
221- go ex .Exec ()
222- return nil
223- })
304+ nctx , cf = context .WithCancel (ctx )
305+ go runCommand (NewContext (nctx , ctx .Logger ), prf , pt , args )
224306
225- return nil
226- }
307+ return nil
308+ case <- ctx .Done ():
309+ logger .Info ("close signal received" )
310+ watch .Close ()
311+ return nil
312+ }
313+ })
227314
228- if err := ex .Exec (); err != nil {
229- return errors .ErrTaskFailed .Wrap (err ).KV ("task" , args .taskName )
230- }
315+ return nil
231316 }
232317
318+ wg .Wait ()
319+
233320 return nil
234321}
0 commit comments