Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 23x 23x 23x 23x 63x 63x 63x 22x 22x 25x 25x 16x 16x 16x 23x 23x 38x 38x 1x 37x 4x 18x 18x 18x 2x 16x 16x 2x 14x 14x 14x 14x 16x 11x | /**
* Pure diff application functions.
* Apply unified diffs to file content without side effects beyond file I/O.
*/
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
import { parsePatch, type DiffHunk } from '../diff/index.js';
/**
* Apply a single hunk to the file content lines.
*/
export function applyHunk(lines: string[], hunk: DiffHunk): string[] {
const result = [...lines];
const oldLines: string[] = [];
const newLines: string[] = [];
for (const line of hunk.lines) {
const prefix = line[0] ?? '';
const content = line.slice(1);
switch (prefix) {
case '-':
oldLines.push(content);
break;
case '+':
newLines.push(content);
break;
case ' ':
case '':
// Context line appears in both old and new
oldLines.push(content);
newLines.push(content);
break;
}
}
// Convert 1-based line number to 0-based index.
// New file diffs use @@ -0,0 +1,N @@, so clamp to 0.
const startIndex = Math.max(0, hunk.oldStart - 1);
for (let i = 0; i < oldLines.length; i++) {
const lineIndex = startIndex + i;
if (lineIndex >= result.length) {
throw new Error(`Hunk context mismatch: line ${lineIndex + 1} doesn't exist`);
}
if (result[lineIndex] !== oldLines[i]) {
throw new Error(
`Hunk context mismatch at line ${lineIndex + 1}: ` +
`expected "${oldLines[i]}", got "${result[lineIndex]}"`
);
}
}
result.splice(startIndex, oldLines.length, ...newLines);
return result;
}
/**
* Apply a unified diff to a file.
* Hunks are applied in reverse order by line number to prevent line shift issues.
*/
export function applyUnifiedDiff(filePath: string, diff: string): void {
if (!existsSync(filePath)) {
throw new Error(`File not found: ${filePath}`);
}
const hunks = parsePatch(diff);
if (hunks.length === 0) {
throw new Error('No valid hunks found in diff');
}
const content = readFileSync(filePath, 'utf-8');
let lines = content.split('\n');
// Sort hunks by oldStart in descending order to apply from bottom to top
const sortedHunks = [...hunks].sort((a, b) => b.oldStart - a.oldStart);
for (const hunk of sortedHunks) {
lines = applyHunk(lines, hunk);
}
writeFileSync(filePath, lines.join('\n'));
}
|