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] // Check for exit code marker oldTrimmed := trimTrailingEmpty(oldExpectedRaw) var oldExitMarker string if len(oldTrimmed) > 0 { last := oldTrimmed[len(oldTrimmed)-1] if exitCodeMarkerRe.MatchString(last) { oldExitMarker = last } } // 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 oldExitMarker != "" { output = append(output, oldExitMarker) } 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 marker to prevent parser from consuming it as one. output = append(output, fmt.Sprintf("[%d]", result.ExitCode)) } for k := 0; k < trailingBlanks; k++ { output = append(output, "") } } i = j - 1 cmdIdx++ } else if cmdIdx == 0 { output = append(output, line) } } return strings.Join(output, "\n") }