fix: report apply-patch partial failures
This commit is contained in:
@@ -102,24 +102,33 @@ function applyPatchFixture(args: string[], patch: string, files: Record<string,
|
||||
}
|
||||
}
|
||||
|
||||
async function applyPatchV2FixtureAttempt(patch: string, files: Record<string, string>): Promise<{ stdout: string; files: Record<string, string>; commands: string[]; error: unknown | null }> {
|
||||
async function applyPatchV2FixtureAttempt(patch: string, files: Record<string, string>, options: { stderrOutput?: boolean } = {}): Promise<{ stdout: string; stderr: string; exitCode: number | null; files: Record<string, string>; commands: string[]; error: unknown | null }> {
|
||||
const state = new Map(Object.entries(files));
|
||||
const pendingWrites = new Map<string, string>();
|
||||
const commands: string[] = [];
|
||||
const stdin = new PassThrough();
|
||||
stdin.end(patch);
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
const stdoutSink = new Writable({
|
||||
write(chunk, _encoding, callback) {
|
||||
stdout += Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
|
||||
callback();
|
||||
},
|
||||
});
|
||||
const stderrSink = new Writable({
|
||||
write(chunk, _encoding, callback) {
|
||||
stderr += Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
|
||||
callback();
|
||||
},
|
||||
});
|
||||
let error: unknown | null = null;
|
||||
let exitCode: number | null = null;
|
||||
try {
|
||||
await runApplyPatchV2({
|
||||
exitCode = await runApplyPatchV2({
|
||||
stdin,
|
||||
stdout: stdoutSink,
|
||||
...(options.stderrOutput === true ? { stderr: stderrSink } : {}),
|
||||
executor: {
|
||||
async run(command, input) {
|
||||
const operation = command[4] ?? "";
|
||||
@@ -199,7 +208,7 @@ async function applyPatchV2FixtureAttempt(patch: string, files: Record<string, s
|
||||
} catch (caught) {
|
||||
error = caught;
|
||||
}
|
||||
return { stdout, files: Object.fromEntries(state), commands, error };
|
||||
return { stdout, stderr, exitCode, files: Object.fromEntries(state), commands, error };
|
||||
}
|
||||
|
||||
async function applyPatchV2ActualShellFixtureAttempt(
|
||||
@@ -734,6 +743,41 @@ export async function runSshArgvGuidanceContract(): Promise<JsonRecord> {
|
||||
failedCompoundV2.error,
|
||||
);
|
||||
|
||||
const failedCompoundVisibleV2 = await applyPatchV2FixtureAttempt([
|
||||
"*** Begin Patch",
|
||||
"*** Update File: first.txt",
|
||||
"@@",
|
||||
"-old first",
|
||||
"+new first",
|
||||
"*** Update File: second.txt",
|
||||
"@@",
|
||||
"-missing second",
|
||||
"+new second",
|
||||
"*** Update File: third.txt",
|
||||
"@@",
|
||||
"-old third",
|
||||
"+new third",
|
||||
"*** End Patch",
|
||||
"",
|
||||
].join("\n"), {
|
||||
"first.txt": "old first\n",
|
||||
"second.txt": "old second\n",
|
||||
"third.txt": "old third\n",
|
||||
}, { stderrOutput: true });
|
||||
assertCondition(failedCompoundVisibleV2.exitCode === 1 && failedCompoundVisibleV2.error === null, "v2 CLI path should return non-zero instead of throwing when stderr is provided", failedCompoundVisibleV2);
|
||||
assertCondition(failedCompoundVisibleV2.stdout === "", "v2 failed CLI path should keep Codex-style empty stdout", failedCompoundVisibleV2);
|
||||
assertCondition(
|
||||
failedCompoundVisibleV2.stderr.includes("failed to find expected lines")
|
||||
&& failedCompoundVisibleV2.stderr.includes("Applied before failure:")
|
||||
&& failedCompoundVisibleV2.stderr.includes("M first.txt")
|
||||
&& failedCompoundVisibleV2.stderr.includes("Failed:")
|
||||
&& failedCompoundVisibleV2.stderr.includes("hunk 2 update second.txt")
|
||||
&& failedCompoundVisibleV2.stderr.includes("Pending after failure:")
|
||||
&& failedCompoundVisibleV2.stderr.includes("hunk 3 update third.txt"),
|
||||
"v2 failed CLI path should print Codex-style stderr plus per-file applied/failed/pending summary",
|
||||
failedCompoundVisibleV2.stderr,
|
||||
);
|
||||
|
||||
const addBeforeFailedUpdateV2 = await applyPatchV2FixtureAttempt([
|
||||
"*** Begin Patch",
|
||||
"*** Add File: hwpod",
|
||||
|
||||
Reference in New Issue
Block a user