87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
import type { CommandResult } from "./run.ts"
|
|
import type { ShoutFile } from "./parse.ts"
|
|
import { matchOutput } from "./match.ts"
|
|
import { isCommentLine } from "./parse.ts"
|
|
import { trimTrailingEmpty } from "./utils.ts"
|
|
|
|
export function rewriteFile(
|
|
file: ShoutFile,
|
|
results: CommandResult[],
|
|
originalContent: string,
|
|
): string {
|
|
const lines = originalContent.split("\n")
|
|
const output: string[] = []
|
|
|
|
let cmdIdx = 0
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const line = lines[i]!
|
|
|
|
if (isCommentLine(line)) {
|
|
// Preserve comment lines as-is
|
|
output.push(line)
|
|
} else if (line.startsWith("$ ") && !line.startsWith("\\$ ")) {
|
|
// Emit the command line as-is
|
|
output.push(line)
|
|
|
|
const cmd = file.commands[cmdIdx]
|
|
const result = results[cmdIdx]
|
|
if (!cmd || !result) {
|
|
cmdIdx++
|
|
continue
|
|
}
|
|
|
|
// Skip past old expected output lines in the original
|
|
let j = i + 1
|
|
while (j < lines.length && !isCommentLine(lines[j]!) && !(lines[j]!.startsWith("$ ") && !lines[j]!.startsWith("\\$ "))) {
|
|
j++
|
|
}
|
|
// Collect old expected lines (before trimming trailing blanks for separator)
|
|
const oldExpectedRaw = lines.slice(i + 1, j)
|
|
|
|
// Check if old expected output had an exit code marker
|
|
const oldTrimmed = trimTrailingEmpty(oldExpectedRaw)
|
|
let oldExitMarker: string | null = null
|
|
if (oldTrimmed.length > 0) {
|
|
const last = oldTrimmed[oldTrimmed.length - 1]!
|
|
if (/^\[(\d+|\*)\]$/.test(last)) {
|
|
oldExitMarker = last
|
|
}
|
|
}
|
|
|
|
// Determine how many trailing blank lines the original had
|
|
let trailingBlanks = 0
|
|
for (let k = oldExpectedRaw.length - 1; k >= 0; k--) {
|
|
if (oldExpectedRaw[k] === "") trailingBlanks++
|
|
else break
|
|
}
|
|
|
|
// If wildcards match, keep original expected output
|
|
if (matchOutput(cmd.expected, result.actual)) {
|
|
// Output original lines as-is
|
|
for (const ol of oldExpectedRaw) output.push(ol)
|
|
} else {
|
|
// Replace with actual output (escape lines starting with "$ ")
|
|
for (const al of result.actual) output.push(escapeDollar(al))
|
|
// Re-add exit code marker if it existed
|
|
if (oldExitMarker) output.push(oldExitMarker)
|
|
// Preserve trailing blank lines as separators
|
|
for (let k = 0; k < trailingBlanks; k++) output.push("")
|
|
}
|
|
|
|
// Skip original expected output lines (we already handled them)
|
|
i = j - 1
|
|
cmdIdx++
|
|
} else if (cmdIdx === 0) {
|
|
// Lines before first command (shouldn't normally exist but preserve them)
|
|
output.push(line)
|
|
}
|
|
}
|
|
|
|
return output.join("\n")
|
|
}
|
|
|
|
function escapeDollar(line: string): string {
|
|
return line.startsWith("$ ") ? "\\" + line : line
|
|
}
|