Show verbose output after run, fix diff context lines

This commit is contained in:
Chris Wanstrath 2026-03-10 13:53:31 -07:00
parent 3730d8995c
commit 064e817d9b
6 changed files with 32 additions and 23 deletions

16
cmd.go
View File

@ -139,19 +139,11 @@ func testCmd() *cobra.Command {
Directives: parsed.Directives, Directives: parsed.Directives,
} }
var onCommand func(Command)
if verbose {
onCommand = func(c Command) {
fmt.Fprintf(os.Stderr, dim(" $ %s\n"), c.Cmd)
}
}
fileResult := runFile(merged, RunOptions{ fileResult := runFile(merged, RunOptions{
CleanEnv: cleanEnv, CleanEnv: cleanEnv,
PathDirs: pathDirs, PathDirs: pathDirs,
EnvVars: envVars, EnvVars: envVars,
Timeout: timeoutDur, Timeout: timeoutDur,
OnCommand: onCommand,
}) })
// Check setup commands for failures // Check setup commands for failures
@ -179,6 +171,12 @@ func testCmd() *cobra.Command {
testResult := evaluateFile(parsed.Path, fileOwnResults, fileResult.Error) testResult := evaluateFile(parsed.Path, fileOwnResults, fileResult.Error)
if verbose && fileResult.Error == "" {
for _, r := range fileOwnResults {
fmt.Fprintf(os.Stderr, dim(" $ %s\n"), r.Command.Cmd)
}
}
if update && len(fileOwnResults) > 0 { if update && len(fileOwnResults) > 0 {
updated := rewriteFile(parsed, fileOwnResults, string(content)) updated := rewriteFile(parsed, fileOwnResults, string(content))
if updated != string(content) { if updated != string(content) {
@ -272,7 +270,7 @@ func testCmd() *cobra.Command {
cmd.Flags().BoolVar(&cleanEnv, "clean-env", false, "Start with empty environment") cmd.Flags().BoolVar(&cleanEnv, "clean-env", false, "Start with empty environment")
cmd.Flags().StringArrayVar(&pathDirs, "path", nil, "Prepend <path> to PATH (repeatable)") cmd.Flags().StringArrayVar(&pathDirs, "path", nil, "Prepend <path> to PATH (repeatable)")
cmd.Flags().StringVar(&timeout, "timeout", "10s", "Per-command timeout") cmd.Flags().StringVar(&timeout, "timeout", "10s", "Per-command timeout")
cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Print each command as it runs") cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Print each command after it runs")
cmd.Flags().IntVar(&portFrom, "port-from", 0, "Auto-assign $PORT starting from <n>") cmd.Flags().IntVar(&portFrom, "port-from", 0, "Auto-assign $PORT starting from <n>")
cmd.Flags().BoolVar(&parallel, "parallel", false, "Run files in parallel") cmd.Flags().BoolVar(&parallel, "parallel", false, "Run files in parallel")

View File

@ -68,12 +68,17 @@ func diff(expected, actual []string) []DiffLine {
if !hasNext { if !hasNext {
result = append(result, DiffLine{Kind: "context", Text: "..."}) result = append(result, DiffLine{Kind: "context", Text: "..."})
for ai < len(actual) {
result = append(result, DiffLine{Kind: "context", Text: actual[ai]})
ai++
}
break break
} }
result = append(result, DiffLine{Kind: "context", Text: "..."}) result = append(result, DiffLine{Kind: "context", Text: "..."})
ei++ ei++
for ai < len(actual) && !matchLine(nextExp, actual[ai]) { for ai < len(actual) && !matchLine(nextExp, actual[ai]) {
result = append(result, DiffLine{Kind: "context", Text: actual[ai]})
ai++ ai++
} }
continue continue

View File

@ -121,7 +121,16 @@ func TestDiffEqual(t *testing.T) {
func TestDiffContext(t *testing.T) { func TestDiffContext(t *testing.T) {
d := diff([]string{"..."}, []string{"a", "b"}) d := diff([]string{"..."}, []string{"a", "b"})
if len(d) != 1 || d[0].Kind != "context" { if len(d) != 3 {
t.Errorf("expected context, got %+v", d) t.Fatalf("expected 3 diff lines, got %d: %+v", len(d), d)
}
if d[0].Kind != "context" || d[0].Text != "..." {
t.Errorf("d[0] = %+v", d[0])
}
if d[1].Kind != "context" || d[1].Text != "a" {
t.Errorf("d[1] = %+v", d[1])
}
if d[2].Kind != "context" || d[2].Text != "b" {
t.Errorf("d[2] = %+v", d[2])
} }
} }

8
run.go
View File

@ -24,7 +24,7 @@ type RunOptions struct {
PathDirs []string PathDirs []string
EnvVars map[string]string EnvVars map[string]string
Timeout time.Duration Timeout time.Duration
OnCommand func(Command)
} }
func buildScript(commands []Command, sentinelPrefix string) string { func buildScript(commands []Command, sentinelPrefix string) string {
@ -168,12 +168,6 @@ func runFile(file ShoutFile, opts RunOptions) FileResult {
} }
}() }()
if opts.OnCommand != nil {
for _, c := range file.Commands {
opts.OnCommand(c)
}
}
// Read stdout with timeout — must start reader BEFORE writing to stdin // Read stdout with timeout — must start reader BEFORE writing to stdin
// to avoid deadlock when pipe buffers fill in both directions. // to avoid deadlock when pipe buffers fill in both directions.
totalTimeout := opts.Timeout * time.Duration(len(file.Commands)) totalTimeout := opts.Timeout * time.Duration(len(file.Commands))

BIN
shout

Binary file not shown.

View File

@ -101,7 +101,7 @@ func rewriteFile(file ShoutFile, results []CommandResult, originalContent string
i = j - 1 i = j - 1
cmdIdx++ cmdIdx++
} else if cmdIdx == 0 || cmdIdx >= len(file.Commands) { } else {
output = append(output, line) output = append(output, line)
} }
} }
@ -118,5 +118,8 @@ func updateExitCodeMarker(cmd Command, actualExitCode int) string {
if actualExitCode != 0 { if actualExitCode != 0 {
return fmt.Sprintf("[%d]", actualExitCode) return fmt.Sprintf("[%d]", actualExitCode)
} }
if cmd.ExitCodeType == ExitCodeWildcard || cmd.ExitCodeType == ExitCodeExact {
return "[0]"
}
return "" return ""
} }