Skip to content

Commit

Permalink
fix: adds killing previous command, when watcher starts new command
Browse files Browse the repository at this point in the history
  • Loading branch information
nxtcoder17 committed Dec 19, 2024
1 parent afcd333 commit eeedbf5
Showing 1 changed file with 179 additions and 162 deletions.
341 changes: 179 additions & 162 deletions runner/run-task.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,177 +55,193 @@ func isTTY() bool {
return ((stdout.Mode() & os.ModeCharDevice) == os.ModeCharDevice) && ((stderr.Mode() & os.ModeCharDevice) == os.ModeCharDevice)
}

func runCommand(ctx Context, prf *types.ParsedRunfile, pt *types.ParsedTask, args runTaskArgs) error {
for _, command := range pt.Commands {
ctx.Debug("running command task", "command.run", command.Run, "parent.task", args.taskName)
func runCommand(ctx Context, prf *types.ParsedRunfile, pt *types.ParsedTask, args runTaskArgs, command types.ParsedCommandJson) error {
ctx.Debug("running command task", "command.run", command.Run, "parent.task", args.taskName)
var wg sync.WaitGroup

if command.If != nil && !*command.If {
ctx.Debug("skipping execution for failed `if`", "command", command.Run)
continue
if command.If != nil && !*command.If {
ctx.Debug("skipping execution for failed `if`", "command", command.Run)
return nil
}

if command.Run != "" {
rt, ok := prf.Tasks[command.Run]
if !ok {
return fmt.Errorf("invalid run target")
}

if command.Run != "" {
rt, ok := prf.Tasks[command.Run]
if !ok {
return fmt.Errorf("invalid run target")
}
rtp, err := parser.ParseTask(ctx, prf, rt)
if err != nil {
return errors.WithErr(err).KV("env-vars", prf.Env)
}

rtp, err := parser.ParseTask(ctx, prf, rt)
if err != nil {
return errors.WithErr(err).KV("env-vars", prf.Env)
}
if err := runTaskCommands(ctx, prf, rtp, args); err != nil {
return errors.WithErr(err).KV("env-vars", prf.Env)
}
return nil
}

if err := runCommand(ctx, prf, rtp, args); err != nil {
return errors.WithErr(err).KV("env-vars", prf.Env)
}
continue
// stdoutR, stdoutW := io.Pipe()
// stderrR, stderrW := io.Pipe()

// wg := sync.WaitGroup{}

// [snippet source](https://rderik.com/blog/identify-if-output-goes-to-the-terminal-or-is-being-redirected-in-golang/)
// stdout, _ := os.Stdout.Stat()
// stderr, _ := os.Stderr.Stat()
// isTTY := ((stdout.Mode() & os.ModeCharDevice) == os.ModeCharDevice) && ((stderr.Mode() & os.ModeCharDevice) == os.ModeCharDevice)
//
// if isTTY {
// go func() {
// defer wg.Done()
// logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s]", strings.Join(trail, "/"))))
// processOutput(os.Stdout, stdoutR, &logPrefix)
//
// stderrPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s/stderr]", strings.Join(trail, "/"))))
// processOutput(os.Stderr, stderrR, &stderrPrefix)
// }()
// } else {
// wg.Add(1)
// go func() {
// defer wg.Done()
// logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s]", strings.Join(trail, "/"))))
// processOutput(os.Stdout, stdoutR, &logPrefix)
// // if pt.Interactive {
// // processOutput(os.Stdout, stdoutR, &logPrefix)
// // return
// // }
// // processOutputLineByLine(os.Stdout, stdoutR, &logPrefix)
// }()
//
// wg.Add(1)
// go func() {
// defer wg.Done()
// logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s/stderr]", strings.Join(trail, "/"))))
// processOutput(os.Stderr, stderrR, &logPrefix)
// // if pt.Interactive {
// // processOutput(os.Stderr, stderrR, &logPrefix)
// // return
// // }
// // processOutputLineByLine(os.Stderr, stderrR, &logPrefix)
// }()
// }

if isTTY() {
borderColor := "#4388cc"
if !isDarkTheme() {
borderColor = "#3d5485"
}
s := lipgloss.NewStyle().BorderForeground(lipgloss.Color(borderColor)).PaddingLeft(1).PaddingRight(1).Border(lipgloss.RoundedBorder(), true, true, true, true)
// labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(borderColor)).Blink(true)

// stdoutR, stdoutW := io.Pipe()
// stderrR, stderrW := io.Pipe()

// wg := sync.WaitGroup{}

// [snippet source](https://rderik.com/blog/identify-if-output-goes-to-the-terminal-or-is-being-redirected-in-golang/)
// stdout, _ := os.Stdout.Stat()
// stderr, _ := os.Stderr.Stat()
// isTTY := ((stdout.Mode() & os.ModeCharDevice) == os.ModeCharDevice) && ((stderr.Mode() & os.ModeCharDevice) == os.ModeCharDevice)
//
// if isTTY {
// go func() {
// defer wg.Done()
// logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s]", strings.Join(trail, "/"))))
// processOutput(os.Stdout, stdoutR, &logPrefix)
//
// stderrPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s/stderr]", strings.Join(trail, "/"))))
// processOutput(os.Stderr, stderrR, &stderrPrefix)
// }()
// } else {
// wg.Add(1)
// go func() {
// defer wg.Done()
// logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s]", strings.Join(trail, "/"))))
// processOutput(os.Stdout, stdoutR, &logPrefix)
// // if pt.Interactive {
// // processOutput(os.Stdout, stdoutR, &logPrefix)
// // return
// // }
// // processOutputLineByLine(os.Stdout, stdoutR, &logPrefix)
// }()
//
// wg.Add(1)
// go func() {
// defer wg.Done()
// logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s/stderr]", strings.Join(trail, "/"))))
// processOutput(os.Stderr, stderrR, &logPrefix)
// // if pt.Interactive {
// // processOutput(os.Stderr, stderrR, &logPrefix)
// // return
// // }
// // processOutputLineByLine(os.Stderr, stderrR, &logPrefix)
// }()
// }

if isTTY() {
borderColor := "#4388cc"
if !isDarkTheme() {
borderColor = "#3d5485"
}
s := lipgloss.NewStyle().BorderForeground(lipgloss.Color(borderColor)).PaddingLeft(1).PaddingRight(1).Border(lipgloss.RoundedBorder(), true, true, true, true)
// labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(borderColor)).Blink(true)
if args.DebugEnv {
fmt.Printf("%s\n", s.Render(padString(fmt.Sprintf("%+v", prf.Env), "DEBUG: env")))
}

if args.DebugEnv {
fmt.Printf("%s\n", s.Render(padString(fmt.Sprintf("%+v", prf.Env), "DEBUG: env")))
}
hlCode := new(bytes.Buffer)
// choose colorschemes from `https://swapoff.org/chroma/playground/`
colorscheme := "catppuccin-macchiato"
if !isDarkTheme() {
colorscheme = "monokailight"
}
// quick.Highlight(hlCode, strings.TrimSpace(command.Command), "bash", "terminal16m", colorscheme)

hlCode := new(bytes.Buffer)
// choose colorschemes from `https://swapoff.org/chroma/playground/`
colorscheme := "catppuccin-macchiato"
if !isDarkTheme() {
colorscheme = "monokailight"
}
// quick.Highlight(hlCode, strings.TrimSpace(command.Command), "bash", "terminal16m", colorscheme)
cmdStr := strings.TrimSpace(command.Command)

cmdStr := strings.TrimSpace(command.Command)
quick.Highlight(hlCode, cmdStr, "bash", "terminal16m", colorscheme)
// cst := styles.Get("gruvbox")
// fmt.Println("cst: ", cst.Name, styles.Fallback.Name, styles.Names())

quick.Highlight(hlCode, cmdStr, "bash", "terminal16m", colorscheme)
// cst := styles.Get("gruvbox")
// fmt.Println("cst: ", cst.Name, styles.Fallback.Name, styles.Names())
// fmt.Printf("%s\n", s.Render(args.taskName+" | "+hlCode.String()))
fmt.Printf("%s\n", s.Render(padString(hlCode.String(), args.taskName)))
}

// fmt.Printf("%s\n", s.Render(args.taskName+" | "+hlCode.String()))
fmt.Printf("%s\n", s.Render(padString(hlCode.String(), args.taskName)))
}
logger2 := logging.New(logging.Options{
Prefix: "[runfile]",
Writer: os.Stderr,
SlogKeyAsPrefix: "task",
})

ex := executor.NewExecutor(executor.ExecutorArgs{
Logger: logger2,
IsInteractive: pt.Interactive,
Command: func(c context.Context) *exec.Cmd {
return CreateCommand(c, CmdArgs{
Shell: pt.Shell,
Env: fn.ToEnviron(pt.Env),
Cmd: command.Command,
WorkingDir: pt.WorkingDir,
interactive: pt.Interactive,
Stdout: os.Stdout,
Stderr: os.Stderr,
})
},
})

logger2 := logging.New(logging.Options{
Prefix: "[runfile]",
Writer: os.Stderr,
SlogKeyAsPrefix: "task",
})
wg.Add(1)
go func() {
defer wg.Done()
<-ctx.Done()
ex.Kill()
}()

ex := executor.NewExecutor(executor.ExecutorArgs{
Logger: logger2,
IsInteractive: pt.Interactive,
Command: func(c context.Context) *exec.Cmd {
return CreateCommand(c, CmdArgs{
Shell: pt.Shell,
Env: fn.ToEnviron(pt.Env),
Cmd: command.Command,
WorkingDir: pt.WorkingDir,
interactive: pt.Interactive,
Stdout: os.Stdout,
Stderr: os.Stderr,
})
},
})
// if task.Watch != nil && (task.Watch.Enable == nil || *task.Watch.Enable) {
// watch, err := watcher.NewWatcher(ctx, watcher.WatcherArgs{
// Logger: logger,
// WatchDirs: append(task.Watch.Dirs, pt.WorkingDir),
// OnlySuffixes: pt.Watch.OnlySuffixes,
// IgnoreSuffixes: pt.Watch.IgnoreSuffixes,
// ExcludeDirs: pt.Watch.ExcludeDirs,
// UseDefaultIgnoreList: true,
// // CooldownDuration: fn.New(1 * time.Second),
// })
// if err != nil {
// return errors.WithErr(err)
// }
//
// go ex.Exec()
//
// go func() {
// <-ctx.Done()
// logger.Debug("fwatcher is closing ...")
// watch.Close()
// <-time.After(200 * time.Millisecond)
// logger.Info("CLOSING..................")
// os.Exit(0)
// }()
//
// watch.WatchEvents(func(event watcher.Event, fp string) error {
// relPath, err := filepath.Rel(fn.Must(os.Getwd()), fp)
// if err != nil {
// return err
// }
// logger.Info(fmt.Sprintf("[RELOADING] due changes in %s", relPath))
// ex.Kill()
// select {
// case <-time.After(100 * time.Millisecond):
// go ex.Exec()
// return nil
// case <-ctx.Done():
// logger.Info("close signal received")
// watch.Close()
// return nil
// }
// })
//
// return nil
// }

if err := ex.Exec(); err != nil {
return errors.ErrTaskFailed.Wrap(err).KV("task", args.taskName)
}

// if task.Watch != nil && (task.Watch.Enable == nil || *task.Watch.Enable) {
// watch, err := watcher.NewWatcher(ctx, watcher.WatcherArgs{
// Logger: logger,
// WatchDirs: append(task.Watch.Dirs, pt.WorkingDir),
// OnlySuffixes: pt.Watch.OnlySuffixes,
// IgnoreSuffixes: pt.Watch.IgnoreSuffixes,
// ExcludeDirs: pt.Watch.ExcludeDirs,
// UseDefaultIgnoreList: true,
// // CooldownDuration: fn.New(1 * time.Second),
// })
// if err != nil {
// return errors.WithErr(err)
// }
//
// go ex.Exec()
//
// go func() {
// <-ctx.Done()
// logger.Debug("fwatcher is closing ...")
// watch.Close()
// <-time.After(200 * time.Millisecond)
// logger.Info("CLOSING..................")
// os.Exit(0)
// }()
//
// watch.WatchEvents(func(event watcher.Event, fp string) error {
// relPath, err := filepath.Rel(fn.Must(os.Getwd()), fp)
// if err != nil {
// return err
// }
// logger.Info(fmt.Sprintf("[RELOADING] due changes in %s", relPath))
// ex.Kill()
// select {
// case <-time.After(100 * time.Millisecond):
// go ex.Exec()
// return nil
// case <-ctx.Done():
// logger.Info("close signal received")
// watch.Close()
// return nil
// }
// })
//
// return nil
// }

if err := ex.Exec(); err != nil {
return errors.ErrTaskFailed.Wrap(err).KV("task", args.taskName)
return nil
}

func runTaskCommands(ctx Context, prf *types.ParsedRunfile, pt *types.ParsedTask, args runTaskArgs) error {
for _, command := range pt.Commands {
if err := runCommand(ctx, prf, pt, args, command); err != nil {
return err
}
}

Expand Down Expand Up @@ -265,7 +281,7 @@ func runTask(ctx Context, prf *types.ParsedRunfile, args runTaskArgs) error {
wg.Add(1)
go func() {
defer wg.Done()
runCommand(NewContext(nctx, ctx.Logger), prf, pt, args)
runTaskCommands(NewContext(nctx, ctx.Logger), prf, pt, args)
}()

if pt.Watch != nil && (pt.Watch.Enable == nil || *pt.Watch.Enable) {
Expand All @@ -276,7 +292,7 @@ func runTask(ctx Context, prf *types.ParsedRunfile, args runTaskArgs) error {
IgnoreSuffixes: pt.Watch.IgnoreSuffixes,
ExcludeDirs: pt.Watch.ExcludeDirs,
UseDefaultIgnoreList: true,
// CooldownDuration: fn.New(1 * time.Second),
CooldownDuration: fn.New(1 * time.Second),
})
if err != nil {
return errors.WithErr(err)
Expand All @@ -286,9 +302,6 @@ func runTask(ctx Context, prf *types.ParsedRunfile, args runTaskArgs) error {
<-ctx.Done()
logger.Debug("fwatcher is closing ...")
watch.Close()
<-time.After(200 * time.Millisecond)
logger.Info("CLOSING..................")
os.Exit(0)
}()

watch.WatchEvents(func(event watcher.Event, fp string) error {
Expand All @@ -302,7 +315,11 @@ func runTask(ctx Context, prf *types.ParsedRunfile, args runTaskArgs) error {
cf()

nctx, cf = context.WithCancel(ctx)
go runCommand(NewContext(nctx, ctx.Logger), prf, pt, args)
wg.Add(1)
go func() {
defer wg.Done()
runTaskCommands(NewContext(nctx, ctx.Logger), prf, pt, args)
}()

return nil
case <-ctx.Done():
Expand Down

0 comments on commit eeedbf5

Please sign in to comment.