diff --git a/cmd.go b/cmd.go index c11367f..6955a94 100644 --- a/cmd.go +++ b/cmd.go @@ -178,9 +178,27 @@ func testCmd() *cobra.Command { } if update && len(fileOwnResults) > 0 { - updated := rewriteFile(parsed, fileOwnResults, string(content)) - if updated != string(content) { - _ = os.WriteFile(filePath, []byte(updated), 0o644) + // Refuse to write if actual output contains "$ " lines — + // they'd be misparsed as commands on the next read. + hasConflict := false + for _, r := range fileOwnResults { + for _, line := range r.Actual { + if strings.HasPrefix(line, "$ ") { + hasConflict = true + break + } + } + if hasConflict { + break + } + } + if hasConflict { + fmt.Fprintf(os.Stderr, "warning: %s: skipping --update because output contains lines starting with '$ '\n", parsed.Path) + } else { + updated := rewriteFile(parsed, fileOwnResults, string(content)) + if updated != string(content) { + _ = os.WriteFile(filePath, []byte(updated), 0o644) + } } } diff --git a/run.go b/run.go index 3aace4b..bf01c17 100644 --- a/run.go +++ b/run.go @@ -162,8 +162,9 @@ func runFile(file ShoutFile, opts RunOptions) FileResult { return FileResult{File: file, TmpDir: tmpDir, Error: err.Error()} } + var waited bool defer func() { - if cmd.Process != nil { + if !waited && cmd.Process != nil { _ = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) } }() @@ -188,6 +189,11 @@ func runFile(file ShoutFile, opts RunOptions) FileResult { select { case r := <-ch: if r.err != nil { + if cmd.Process != nil { + _ = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL) + } + _ = cmd.Wait() + waited = true return FileResult{File: file, TmpDir: tmpDir, Error: r.err.Error()} } output = r.data @@ -197,10 +203,12 @@ func runFile(file ShoutFile, opts RunOptions) FileResult { } <-ch // drain the reader goroutine so pipe FDs are released _ = cmd.Wait() + waited = true return FileResult{File: file, TmpDir: tmpDir, Error: "Timeout reading output"} } _ = cmd.Wait() + waited = true outputs, exitCodesList := parseSentinelOutput(string(output), len(file.Commands), sentinel) diff --git a/shout b/shout index 35d7112..8aa9845 100755 Binary files a/shout and b/shout differ diff --git a/update.go b/update.go index 5628aee..b71894f 100644 --- a/update.go +++ b/update.go @@ -79,8 +79,6 @@ func rewriteFile(file ShoutFile, results []CommandResult, originalContent string marker := updateExitCodeMarker(cmd, result.ExitCode) if marker != "" { output = append(output, marker) - } else if len(content) > 0 && exitCodeMarkerRe.MatchString(content[len(content)-1]) { - output = append(output, "[0]") } for k := 0; k < rawTrailing; k++ { output = append(output, "")