go-shout/update.go

82 lines
1.9 KiB
Go

package main
import (
"fmt"
"regexp"
"strings"
)
var exitCodeMarkerRe = regexp.MustCompile(`^\[(\d+|\*)\]$`)
func rewriteFile(file ShoutFile, results []CommandResult, originalContent string) string {
lines := strings.Split(originalContent, "\n")
var output []string
cmdIdx := 0
for i := 0; i < len(lines); i++ {
line := lines[i]
if strings.HasPrefix(line, "$ ") {
output = append(output, line)
if cmdIdx >= len(file.Commands) || cmdIdx >= len(results) {
// Out of bounds — skip past expected output, preserving original lines
j := i + 1
for j < len(lines) && !strings.HasPrefix(lines[j], "$ ") {
j++
}
output = append(output, lines[i+1:j]...)
i = j - 1
cmdIdx++
continue
}
cmd := file.Commands[cmdIdx]
result := results[cmdIdx]
// Skip past old expected output lines
j := i + 1
for j < len(lines) && !strings.HasPrefix(lines[j], "$ ") {
j++
}
oldExpectedRaw := lines[i+1 : j]
// Count trailing blank lines
trailingBlanks := 0
for k := len(oldExpectedRaw) - 1; k >= 0; k-- {
if oldExpectedRaw[k] == "" {
trailingBlanks++
} else {
break
}
}
// If wildcards match, keep original
if matchOutput(cmd.Expected, result.Actual) {
output = append(output, oldExpectedRaw...)
} else {
output = append(output, result.Actual...)
if result.ExitCode != 0 {
output = append(output, fmt.Sprintf("[%d]", result.ExitCode))
} else if len(result.Actual) > 0 && exitCodeMarkerRe.MatchString(result.Actual[len(result.Actual)-1]) {
// Actual output's last line looks like an exit code marker.
// Add an explicit [0] to prevent parser from consuming it.
output = append(output, "[0]")
}
for k := 0; k < trailingBlanks; k++ {
output = append(output, "")
}
}
i = j - 1
cmdIdx++
} else if cmdIdx == 0 || cmdIdx >= len(file.Commands) {
output = append(output, line)
}
}
return strings.Join(output, "\n")
}