Skip to content

Commit

Permalink
fix: --cmd breaking with >1 argument, kill child processes correctly (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
headblockhead authored Oct 1, 2023
1 parent 5f2361c commit cdb04a6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
13 changes: 9 additions & 4 deletions cmd/templ/generatecmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ func Run(args Arguments) (err error) {
select {
case <-signalChan: // First signal, cancel context.
fmt.Println("\nCancelling...")
err = run.KillAll()
if err != nil {
fmt.Printf("Error killing command: %v\n", err)
}
cancel()
case <-ctx.Done():
}
Expand Down Expand Up @@ -133,11 +137,12 @@ func runCmd(ctx context.Context, args Arguments) (err error) {
if _, err := run.Run(ctx, args.Path, args.Command); err != nil {
fmt.Printf("Error starting command: %v\n", err)
}
// Send server-sent event.
if p != nil {
p.SendSSE("message", "reload")
}
}
// Send server-sent event.
if p != nil {
p.SendSSE("message", "reload")
}

if !firstRunComplete && p != nil {
go func() {
fmt.Printf("Proxying from %s to target: %s\n", p.URL, p.Target.String())
Expand Down
38 changes: 32 additions & 6 deletions cmd/templ/generatecmd/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,65 @@ package run

import (
"context"
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"sync"
"syscall"
)

var m = &sync.Mutex{}
var running = map[string]*exec.Cmd{}

func KillAll() (err error) {
m.Lock()
defer m.Unlock()
for _, cmd := range running {
if runtime.GOOS == "windows" {
kill := exec.Command("TASKKILL", "/T", "/F", "/PID", strconv.Itoa(cmd.Process.Pid))
kill.Stderr = os.Stderr
kill.Stdout = os.Stdout
err := kill.Run()
if err != nil {
return err
}
continue
}
err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
if err != nil {
return err
}
}
running = map[string]*exec.Cmd{}
return
}

func Run(ctx context.Context, workingDir, input string) (cmd *exec.Cmd, err error) {
m.Lock()
defer m.Unlock()
cmd, ok := running[input]
if ok {
if err = cmd.Process.Kill(); err != nil {
return nil, fmt.Errorf("failed to kill existing process: %w", err)
if err = KillAll(); err != nil {
return
}
delete(running, input)
}

parts := strings.SplitN(input, " ", 2)
parts := strings.Fields(input)
executable := parts[0]
args := []string{}
if len(parts) > 1 {
args = append(args, parts[1])
args = append(args, parts[1:]...)
}

cmd = exec.CommandContext(ctx, executable, args...)
cmd = exec.Command(executable, args...)
cmd.Env = os.Environ()
cmd.Dir = workingDir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
running[input] = cmd
err = cmd.Start()
return
Expand Down

0 comments on commit cdb04a6

Please sign in to comment.