fix: optimize Windows apply-patch fs path
This commit is contained in:
@@ -632,6 +632,7 @@ function isBulkReadFailure(error: unknown): boolean {
|
||||
}
|
||||
|
||||
function shouldUseBulkUpdatePath(executor: ApplyPatchV2Executor, hunks: PatchHunk[]): boolean {
|
||||
const isFsBulkPath = executor.fs !== undefined;
|
||||
if (executor.fs !== undefined) {
|
||||
if (executor.fs.readFiles === undefined || executor.fs.applyReplacementsBulk === undefined) return false;
|
||||
} else if (!executor.run) {
|
||||
@@ -643,7 +644,7 @@ function shouldUseBulkUpdatePath(executor: ApplyPatchV2Executor, hunks: PatchHun
|
||||
if (paths.has(hunk.path)) return false;
|
||||
paths.add(hunk.path);
|
||||
}
|
||||
return paths.size >= 2;
|
||||
return isFsBulkPath ? paths.size >= 1 : paths.size >= 2;
|
||||
}
|
||||
|
||||
async function applyPatchV2UpdateHunksBulk(executor: ApplyPatchV2Executor, hunks: Array<Extract<PatchHunk, { kind: "update" }>>): Promise<ApplyPatchV2Plan> {
|
||||
@@ -733,6 +734,7 @@ function formatApplyPatchFailure(error: unknown): string {
|
||||
const outcomes = Array.isArray(details.outcomes) ? details.outcomes as ApplyPatchV2Outcome[] : [];
|
||||
const lines = [`${message.trimEnd()}`];
|
||||
appendParserFailureHint(lines, message, details);
|
||||
appendRemoteOperationFailureDetails(lines, details);
|
||||
appendExpectedLinesFailureHint(lines, details);
|
||||
if (outcomes.length > 1 || outcomes.some((item) => item.status === "applied")) {
|
||||
lines.push("Patch status:");
|
||||
@@ -757,6 +759,72 @@ function appendParserFailureHint(lines: string[], message: string, details: Reco
|
||||
}
|
||||
}
|
||||
|
||||
function appendRemoteOperationFailureDetails(lines: string[], details: Record<string, unknown>): void {
|
||||
const remote = remoteOperationFailureRecord(details);
|
||||
if (remote === null) return;
|
||||
const summaryFields = [
|
||||
["operation", stringField(remote, "operation")],
|
||||
["route", stringField(remote, "route")],
|
||||
["file", stringField(remote, "filePath") ?? stringField(remote, "path")],
|
||||
["targetCount", numberOrStringField(remote, "targetCount")],
|
||||
["inputBytes", numberOrStringField(remote, "inputBytes")],
|
||||
["expectedBytes", numberOrStringField(remote, "expectedBytes")],
|
||||
["sha256", stringField(remote, "expectedSha256") ?? stringField(remote, "sha256")],
|
||||
["elapsedMs", numberOrStringField(remote, "remoteElapsedMs")],
|
||||
["landed", booleanOrStringField(remote, "landed")],
|
||||
["exitCode", numberOrStringField(remote, "exitCode")],
|
||||
].filter(([, value]) => value !== undefined && value !== null && value !== "");
|
||||
if (summaryFields.length > 0) {
|
||||
lines.push(`Remote operation: ${summaryFields.map(([key, value]) => `${key}=${value}`).join(" ")}`);
|
||||
}
|
||||
const stderrTail = stringField(remote, "stderrTail") ?? stringField(remote, "stderr");
|
||||
if (stderrTail !== undefined && stderrTail.trim().length > 0) {
|
||||
lines.push("Remote stderr tail:");
|
||||
appendQuotedBlock(lines, stderrTail.trim(), 8, 1200);
|
||||
}
|
||||
const stdoutTail = stringField(remote, "stdoutTail") ?? stringField(remote, "stdout");
|
||||
if (stdoutTail !== undefined && stdoutTail.trim().length > 0) {
|
||||
lines.push("Remote stdout tail:");
|
||||
appendQuotedBlock(lines, stdoutTail.trim(), 6, 900);
|
||||
}
|
||||
}
|
||||
|
||||
function remoteOperationFailureRecord(details: Record<string, unknown>): Record<string, unknown> | null {
|
||||
if (typeof details.operation === "string") return details;
|
||||
const cause = recordValue(details.cause);
|
||||
if (cause !== null) {
|
||||
const nested = remoteOperationFailureRecord(cause);
|
||||
if (nested !== null) return nested;
|
||||
}
|
||||
const failed = recordValue(details.failed);
|
||||
const failedError = recordValue(failed?.error);
|
||||
const failedDetails = recordValue(failedError?.details);
|
||||
if (failedDetails !== null) {
|
||||
const nested = remoteOperationFailureRecord(failedDetails);
|
||||
if (nested !== null) return nested;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function stringField(record: Record<string, unknown>, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
function numberOrStringField(record: Record<string, unknown>, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
||||
if (typeof value === "string" && value.length > 0) return value;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function booleanOrStringField(record: Record<string, unknown>, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
if (typeof value === "boolean") return String(value);
|
||||
if (typeof value === "string" && value.length > 0) return value;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function appendExpectedLinesFailureHint(lines: string[], details: Record<string, unknown>): void {
|
||||
const cause = recordValue(details.cause) ?? details;
|
||||
const expected = typeof cause.expected === "string" ? cause.expected : "";
|
||||
@@ -941,12 +1009,16 @@ async function readRemoteText(executor: ApplyPatchV2Executor, target: string): P
|
||||
|
||||
async function readRemoteTextsBulk(executor: ApplyPatchV2Executor, targets: string[]): Promise<Map<string, string>> {
|
||||
if (targets.length === 0) return new Map();
|
||||
if (executor.fs?.readFiles !== undefined && targets.length > 1) {
|
||||
const files = await executor.fs.readFiles(targets);
|
||||
for (const target of targets) {
|
||||
if (!files.has(target)) throw new ApplyPatchV2Error("remote apply-patch v2 fs bulk read omitted target", { target });
|
||||
if (executor.fs?.readFiles !== undefined) {
|
||||
try {
|
||||
const files = await executor.fs.readFiles(targets);
|
||||
for (const target of targets) {
|
||||
if (!files.has(target)) throw new ApplyPatchV2Error("remote apply-patch v2 fs bulk read omitted target", { target });
|
||||
}
|
||||
return files;
|
||||
} catch (error) {
|
||||
if (!isBulkReadFailure(error)) throw error;
|
||||
}
|
||||
return files;
|
||||
}
|
||||
if (executor.fs || targets.length === 1) {
|
||||
const files = new Map<string, string>();
|
||||
|
||||
Reference in New Issue
Block a user