Files
openchamber/packages/ui/src/lib/diff/patchFileDiff.ts
T
00821700de chore: remove dead code (59 unused files + ~125 unused exports) (#1835)
* chore: remove dead/unreferenced files across ui, vscode

Remove 59 unused source files (components, hooks, lib utils, stores,
barrels, and orphaned vscode github modules) that are not imported by
any entry-reachable code. Also drop a stale test mock for the removed
execCommands module.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* refactor: remove unused exported symbols (types, functions, consts, hooks)

Remove exported symbols whose identifier is referenced nowhere in the
repository (verified via repo-wide search), across ui types/contracts,
lib utilities, sync layer, stores, and components. Also drop the few
imports/private helpers orphaned by these removals.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* refactor: remove more unused exports (desktop, shortcuts, worktree, vscode)

Continue removing repo-wide unreferenced exported functions, consts and
types across lib/desktop, shortcuts, worktreeSessionCreator, sync, and
vscode gitService, with cascading orphaned helpers/imports cleaned up.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>

* chore: add dead-code cleanup tooling

* refactor: checkpoint dead-code cleanup

* refactor: remove dead-code suppressions

---------

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-06-26 19:27:53 +03:00

179 lines
5.4 KiB
TypeScript

import {
parseDiffFromFile,
parsePatchFiles,
processFile,
trimPatchContext,
type FileDiffMetadata,
} from '@pierre/diffs';
const PATCH_DIFF_CACHE_LIMIT = 64;
const DEFAULT_PATCH_CONTEXT_LINES = 3;
const patchFileDiffCache = new Map<string, FileDiffMetadata>();
export const fileDiffFromPatch = (
file: string,
patch: string,
contextLines = DEFAULT_PATCH_CONTEXT_LINES
): FileDiffMetadata => {
const key = `${file}\0${contextLines}\0${patch}`;
const cached = patchFileDiffCache.get(key);
if (cached) {
patchFileDiffCache.delete(key);
patchFileDiffCache.set(key, cached);
return cached;
}
const completeContents = completePatchContents(patch);
const value = completeContents
? (processFile(trimPatchContext(patch, contextLines), {
oldFile: { name: file, contents: completeContents.before },
newFile: { name: file, contents: completeContents.after },
}) ?? emptyFileDiff(file))
: (parsePatchFiles(withPatchHeader(file, patch))[0]?.files[0] ?? emptyFileDiff(file));
patchFileDiffCache.set(key, value);
while (patchFileDiffCache.size > PATCH_DIFF_CACHE_LIMIT) {
const firstKey = patchFileDiffCache.keys().next().value;
if (!firstKey) break;
patchFileDiffCache.delete(firstKey);
}
return value;
};
const withPatchHeader = (file: string, patch: string): string => {
if (!patch.trim()) {
return patch;
}
if (patch.startsWith('diff --git ') || /^--- [^\n]*\r?\n\+\+\+ /m.test(patch)) {
return patch;
}
return `Index: ${file}\n===================================================================\n--- ${file}\t\n+++ ${file}\t\n${patch}`;
};
const completePatchContents = (patch: string): { before: string; after: string } | undefined => {
if (!patch.startsWith('diff --git ') && !/^--- [^\n]*\t?\r?\n\+\+\+ [^\n]*\t?(?:\r?\n|$)/m.test(patch)) {
return undefined;
}
const hunkMatches = [...patch.matchAll(/^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@[^\n]*(?:\r?\n|$)/gm)];
if (hunkMatches.length !== 1) {
return undefined;
}
const hunk = hunkMatches[0];
const oldStart = Number.parseInt(hunk[1] ?? '', 10);
const newStart = Number.parseInt(hunk[2] ?? '', 10);
if (oldStart > 1 || newStart > 1 || !Number.isFinite(oldStart) || !Number.isFinite(newStart)) {
return undefined;
}
const hunkStart = (hunk.index ?? 0) + hunk[0].length;
const body = patch.slice(hunkStart);
const before: Array<{ text: string; newline: boolean }> = [];
const after: Array<{ text: string; newline: boolean }> = [];
let previous: '-' | '+' | ' ' | undefined;
for (const rawLine of body.split(/\r?\n/)) {
if (rawLine.startsWith('diff --git ') || rawLine.startsWith('@@ ')) {
break;
}
if (rawLine.startsWith('\\')) {
if (previous === '-' || previous === ' ') {
const value = before.at(-1);
if (value) value.newline = false;
}
if (previous === '+' || previous === ' ') {
const value = after.at(-1);
if (value) value.newline = false;
}
continue;
}
if (rawLine.startsWith('-')) {
before.push({ text: rawLine.slice(1), newline: true });
previous = '-';
continue;
}
if (rawLine.startsWith('+')) {
after.push({ text: rawLine.slice(1), newline: true });
previous = '+';
continue;
}
if (!rawLine.startsWith(' ')) {
continue;
}
before.push({ text: rawLine.slice(1), newline: true });
after.push({ text: rawLine.slice(1), newline: true });
previous = ' ';
}
return {
before: joinPatchLines(before),
after: joinPatchLines(after),
};
};
const joinPatchLines = (lines: Array<{ text: string; newline: boolean }>): string =>
lines.map((line) => line.text + (line.newline ? '\n' : '')).join('');
const emptyFileDiff = (file: string): FileDiffMetadata =>
parseDiffFromFile({ name: file, contents: '' }, { name: file, contents: '' });
/**
* Split a unified diff patch for a single file into standalone per-hunk patches.
*
* Each returned patch preserves the original file header (everything before the
* first `@@` hunk header) plus exactly one hunk, producing a patch that can be
* fed to `git apply` on its own.
*
* Returns an empty array when no hunk headers are present.
*/
export const splitPatchIntoHunks = (patch: string): string[] => {
if (!patch) return [];
const lines = patch.split(/\r?\n/);
const hunkHeaderRegex = /^@@\s/;
const headerLines: string[] = [];
let firstHunk = 0;
while (firstHunk < lines.length && !hunkHeaderRegex.test(lines[firstHunk] ?? '')) {
headerLines.push(lines[firstHunk]);
firstHunk += 1;
}
if (firstHunk >= lines.length) {
return [];
}
const hunks: string[][] = [];
for (let index = firstHunk; index < lines.length; index += 1) {
const line = lines[index];
if (hunkHeaderRegex.test(line ?? '')) {
hunks.push([...headerLines, line]);
} else if (hunks.length > 0) {
hunks[hunks.length - 1].push(line ?? '');
}
}
return hunks.map((hunkLines) => hunkLines.join('\n'))
.filter((hunk) => hunk.trim().length > 0)
.map((hunk) => (hunk.endsWith('\n') ? hunk : `${hunk}\n`));
};
/**
* Extract a standalone patch for a single hunk by zero-based index.
*
* Returns `null` when the index is out of range or the patch has no hunks.
*/
export const extractHunkPatch = (patch: string, hunkIndex: number): string | null => {
if (!Number.isInteger(hunkIndex) || hunkIndex < 0) return null;
const hunks = splitPatchIntoHunks(patch);
return hunks[hunkIndex] ?? null;
};