Something went wrong. Try again.
cusotme ui of tangled.org
Something went wrong. Try again.
2.3 kB · 90 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990// Minimal unified-diff / git format-patch parser for pull request render.// Handles the real `patch` field stored on sh.tangled.repo.pull records.
export interface DiffLine { type: "add" | "del" | "ctx"; text: string;}
export interface DiffHunk { header: string; lines: DiffLine[];}
export interface DiffFile { from: string; to: string; hunks: DiffHunk[]; binary: boolean;}
function cleanPath(p: string): string { return p .replace(/^a\//, "") .replace(/^b\//, "");}
export function parsePatch(patch: string): DiffFile[] { if (!patch) return []; const files: DiffFile[] = []; let file: DiffFile | null = null; let hunk: DiffHunk | null = null;
const lines = patch.replace(/\r\n/g, "\n").split("\n");
for (const raw of lines) { const line = raw;
if (line.startsWith("diff --git ")) { if (file) files.push(file); file = { from: "", to: "", hunks: [], binary: false }; hunk = null; const m = /diff --git a\/(\S+) b\/(\S+)/.exec(line); file.from = m ? cleanPath(m[1]) : ""; file.to = m ? cleanPath(m[2]) : ""; continue; }
if (!file) continue;
if (line.startsWith("Binary files ") || line.startsWith("GIT binary patch")) { file.binary = true; continue; }
if (line.startsWith("@@ ")) { hunk = { header: line, lines: [] }; file.hunks.push(hunk); continue; }
if (hunk) { const first = line[0]; if (first === "+") { hunk.lines.push({ type: "add", text: line.slice(1) }); } else if (first === "-") { hunk.lines.push({ type: "del", text: line.slice(1) }); } else if (line === "\\ No newline at end of file") { hunk.lines.push({ type: "ctx", text: line }); } else { hunk.lines.push({ type: "ctx", text: line }); } } } if (file) files.push(file); return files;}
export function patchStats(patch: string): { additions: number; deletions: number; files: number } { const stats = { additions: 0, deletions: 0, files: 0 }; for (const f of parsePatch(patch)) { stats.files += 1; for (const h of f.hunks) { for (const l of h.lines) { if (l.type === "add") stats.additions += 1; if (l.type === "del") stats.deletions += 1; } } } return stats;}