@epic-web/workshop-utils 6.30.2 → 6.30.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/diff.server.js
CHANGED
|
@@ -286,8 +286,8 @@ async function getDiffFilesImpl(app1, app2) {
|
|
|
286
286
|
app1CopyPath,
|
|
287
287
|
app2CopyPath,
|
|
288
288
|
], { cwd: diffTmpDir }).catch((e) => e);
|
|
289
|
-
void fsExtra.remove(app1CopyPath);
|
|
290
|
-
void fsExtra.remove(app2CopyPath);
|
|
289
|
+
void fsExtra.remove(app1CopyPath).catch(() => { });
|
|
290
|
+
void fsExtra.remove(app2CopyPath).catch(() => { });
|
|
291
291
|
const typesMap = {
|
|
292
292
|
ChangedFile: 'modified',
|
|
293
293
|
AddedFile: 'added',
|
|
@@ -348,8 +348,8 @@ async function getDiffCodeImpl(app1, app2) {
|
|
|
348
348
|
'--ignore-blank-lines',
|
|
349
349
|
'--ignore-space-change',
|
|
350
350
|
], { cwd: diffTmpDir }).catch((e) => e);
|
|
351
|
-
void fsExtra.remove(app1CopyPath);
|
|
352
|
-
void fsExtra.remove(app2CopyPath);
|
|
351
|
+
void fsExtra.remove(app1CopyPath).catch(() => { });
|
|
352
|
+
void fsExtra.remove(app2CopyPath).catch(() => { });
|
|
353
353
|
const parsed = parseGitDiff(diffOutput);
|
|
354
354
|
if (!parsed.files.length) {
|
|
355
355
|
markdownLines.push('<div className="m-5 inline-flex items-center justify-center bg-foreground px-1 py-0.5 font-mono text-sm uppercase text-background">No changes</div>');
|
|
@@ -435,8 +435,8 @@ export async function getDiffOutputWithRelativePaths(app1, app2) {
|
|
|
435
435
|
'--ignore-blank-lines',
|
|
436
436
|
'--ignore-space-change',
|
|
437
437
|
], { cwd: diffTmpDir }).catch((e) => e);
|
|
438
|
-
void fsExtra.remove(app1CopyPath);
|
|
439
|
-
void fsExtra.remove(app2CopyPath);
|
|
438
|
+
void fsExtra.remove(app1CopyPath).catch(() => { });
|
|
439
|
+
void fsExtra.remove(app2CopyPath).catch(() => { });
|
|
440
440
|
return diffOutput
|
|
441
441
|
.replaceAll(app1CopyPath.slice(1), '.')
|
|
442
442
|
.replaceAll(app2CopyPath.slice(1), '.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.server.js","sourceRoot":"","sources":["../../src/diff.server.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { getEnv } from './init-env.js'\n\nimport os from 'os'\nimport path from 'path'\nimport { type CacheEntry } from '@epic-web/cachified'\nimport { execa } from 'execa'\nimport fsExtra from 'fs-extra'\nimport ignore from 'ignore'\nimport parseGitDiff, { type AnyFileChange } from 'parse-git-diff'\nimport { bundledLanguagesInfo } from 'shiki/langs'\nimport {\n\tgetForceFreshForDir,\n\tgetRelativePath,\n\tgetWorkshopRoot,\n\tmodifiedTimes,\n\ttype App,\n} from './apps.server.js'\nimport {\n\tcachified,\n\tcopyUnignoredFilesCache,\n\tdiffCodeCache,\n\tdiffFilesCache,\n} from './cache.server.js'\nimport { compileMarkdownString } from './compile-mdx.server.js'\nimport { modifiedMoreRecentlyThan } from './modified-time.server.js'\nimport { type Timings } from './timing.server.js'\n\nconst epicshopTempDir = path.join(os.tmpdir(), 'epicshop')\n\nconst isDeployed = getEnv().EPICSHOP_DEPLOYED\n\nconst diffTmpDir = path.join(epicshopTempDir, 'diff')\n\n/**\n * Converts a diff file path to a relative path for display and lookup.\n * - Removes leading/trailing quotes.\n * - Strips diff prefixes like a/, b/, .\\a\\, .\\b\\, ./a/, ./b/ (for both POSIX and Windows).\n * - Normalizes the path separators.\n * - Removes the diff temp directory prefix and splits out the actual relative path.\n */\nfunction diffPathToRelative(filePath: string) {\n\tlet normalizedPath = path.normalize(\n\t\tfilePath\n\t\t\t.replace(/^[\"']|[\"']$/g, '')\n\t\t\t.replace(/^(\\.\\\\[ab]\\\\|\\.\\/[ab]\\/|[ab][\\\\/])/, ''),\n\t)\n\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tconst [workshopRootDirname, appId, id, ...relativePath] = normalizedPath\n\t\t.replace(\n\t\t\tprocess.platform === 'win32' || normalizedPath.startsWith(path.sep)\n\t\t\t\t? `${diffTmpDir}${path.sep}`\n\t\t\t\t: `${diffTmpDir.slice(1)}${path.sep}`,\n\t\t\t'',\n\t\t)\n\t\t.split(path.sep)\n\n\treturn relativePath.join(path.sep)\n}\n\nfunction getLanguage(ext: string) {\n\treturn (\n\t\tbundledLanguagesInfo.find((l) => l.id === ext || l.aliases?.includes(ext))\n\t\t\t?.id ?? 'text'\n\t)\n}\n\nfunction getFileCodeblocks(\n\tfile: ReturnType<typeof parseGitDiff>['files'][number],\n\tfilePathApp1: string,\n\tfilePathApp2: string,\n\ttype: string,\n) {\n\tif (!file.chunks.length) {\n\t\treturn [\n\t\t\t`<p className=\"m-0 p-4 border-b text-muted-foreground\">No changes</p>`,\n\t\t]\n\t}\n\tconst filepath = diffPathToRelative(\n\t\tfile.type === 'RenamedFile' ? file.pathAfter : file.path,\n\t)\n\tconst extension = path.extname(filepath).slice(1)\n\tconst lang = getLanguage(extension)\n\tconst pathToCopy = file.type === 'RenamedFile' ? file.pathBefore : file.path\n\tconst relativePath = diffPathToRelative(pathToCopy)\n\tconst markdownLines = []\n\tfor (const chunk of file.chunks) {\n\t\tconst removedLineNumbers = []\n\t\tconst addedLineNumbers = []\n\t\tconst lines = []\n\t\tlet toStartLine = 0\n\t\tlet startLine = 1\n\t\tif (chunk.type === 'BinaryFilesChunk') {\n\t\t\tlines.push(\n\t\t\t\ttype === 'AddedFile'\n\t\t\t\t\t? `Binary file added`\n\t\t\t\t\t: type === 'DeletedFile'\n\t\t\t\t\t\t? 'Binary file deleted'\n\t\t\t\t\t\t: 'Binary file changed',\n\t\t\t)\n\t\t} else {\n\t\t\tstartLine =\n\t\t\t\tchunk.type === 'Chunk'\n\t\t\t\t\t? chunk.fromFileRange.start\n\t\t\t\t\t: chunk.type === 'CombinedChunk'\n\t\t\t\t\t\t? chunk.fromFileRangeA.start\n\t\t\t\t\t\t: 1\n\t\t\ttoStartLine = chunk.toFileRange.start\n\t\t\tfor (\n\t\t\t\tlet lineNumber = 0;\n\t\t\t\tlineNumber < chunk.changes.length;\n\t\t\t\tlineNumber++\n\t\t\t) {\n\t\t\t\tconst change = chunk.changes[lineNumber]\n\t\t\t\tif (!change) continue\n\t\t\t\tlines.push(change.content)\n\t\t\t\tswitch (change.type) {\n\t\t\t\t\tcase 'AddedLine': {\n\t\t\t\t\t\taddedLineNumbers.push(startLine + lineNumber)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'DeletedLine': {\n\t\t\t\t\t\tremovedLineNumbers.push(startLine + lineNumber)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst params = [\n\t\t\t['filename', relativePath.replace(/\\\\/g, '\\\\\\\\')],\n\t\t\t['start', startLine.toString()],\n\t\t\tremovedLineNumbers.length\n\t\t\t\t? ['remove', removedLineNumbers.join(',')]\n\t\t\t\t: null,\n\t\t\taddedLineNumbers.length ? ['add', addedLineNumbers.join(',')] : null,\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.map(([key, value]) => `${key}=${value}`)\n\t\t\t.join(' ')\n\n\t\tconst launchEditorClassName =\n\t\t\t'border hover:bg-foreground/20 rounded px-2 py-0.5 font-mono text-xs font-semibold'\n\n\t\tfunction launchEditor(appNum: number, line: number) {\n\t\t\tline ||= 1 // handle 0\n\t\t\tif (isDeployed) {\n\t\t\t\tif (type === 'DeletedFile' && appNum === 2) return ''\n\t\t\t\tif (type === 'AddedFile' && appNum === 1) return ''\n\t\t\t}\n\n\t\t\tconst label =\n\t\t\t\t(type === 'AddedFile' && appNum === 1) ||\n\t\t\t\t(type === 'DeletedFile' && appNum === 2)\n\t\t\t\t\t? `CREATE in APP ${appNum}`\n\t\t\t\t\t: `OPEN in APP ${appNum}`\n\t\t\tconst file = JSON.stringify(appNum === 1 ? filePathApp1 : filePathApp2)\n\t\t\tconst fixedTitle = getRelativePath(file)\n\n\t\t\treturn `\n<LaunchEditor file=${file} line={${line}}>\n\t<span title=\"${fixedTitle}\" className=\"${launchEditorClassName}\">${label}</span>\n</LaunchEditor>`\n\t\t}\n\n\t\tmarkdownLines.push(`\n<div className=\"relative\">\n\n\\`\\`\\`${lang} ${params}\n${lines.join('\\n')}\n\\`\\`\\`\n\n<div className=\"flex gap-4 absolute top-1 right-3 items-center\">\n\t${launchEditor(1, startLine)}\n\t<div className=\"display-alt-down flex gap-2\">\n\t\t<LaunchEditor file=${JSON.stringify(\n\t\t\tfilePathApp1,\n\t\t)} syncTo={{file: ${JSON.stringify(filePathApp2)}}}>\n\t\t\t<span className=\"block ${launchEditorClassName}\">\n\t\t\t\t<Icon name=\"ArrowLeft\" title=\"Copy app 2 file to app 1\" />\n\t\t\t</span>\n\t\t</LaunchEditor>\n\t\t<LaunchEditor file=${JSON.stringify(\n\t\t\tfilePathApp2,\n\t\t)} syncTo={{file: ${JSON.stringify(filePathApp1)}}}>\n\t\t\t<span className=\"block ${launchEditorClassName}\">\n\t\t\t\t<Icon name=\"ArrowRight\" title=\"Copy app 1 file to app 2\" />\n\t\t\t</span>\n\t\t</LaunchEditor>\n\t</div>\n\t${launchEditor(2, toStartLine)}\n</div>\n\n</div>\n`)\n\t}\n\treturn markdownLines\n}\n\nconst DEFAULT_IGNORE_PATTERNS = [\n\t'**/README.*',\n\t'**/package-lock.json',\n\t'**/.DS_Store',\n\t'**/.vscode',\n\t'**/.idea',\n\t'**/.git',\n\t'**/*.db',\n\t'**/epicshop/**',\n]\n\nasync function copyUnignoredFiles(\n\tsrcDir: string,\n\tdestDir: string,\n\tignoreList: Array<string>,\n) {\n\tconst key = `COPY_${srcDir}__${destDir}__${ignoreList.join('_')}`\n\tawait cachified({\n\t\tkey,\n\t\tcache: copyUnignoredFilesCache,\n\t\tforceFresh: await getForceFreshForDir(\n\t\t\tcopyUnignoredFilesCache.get(key),\n\t\t\tsrcDir,\n\t\t),\n\t\tasync getFreshValue() {\n\t\t\t// @ts-ignore 🤷♂️ weird module stuff\n\t\t\tconst ig = ignore().add(ignoreList)\n\n\t\t\tawait fsExtra.remove(destDir)\n\t\t\tawait fsExtra.copy(srcDir, destDir, {\n\t\t\t\tfilter: async (file) => {\n\t\t\t\t\tif (file === srcDir) return true\n\t\t\t\t\treturn !ig.ignores(path.relative(srcDir, file))\n\t\t\t\t},\n\t\t\t})\n\t\t},\n\t})\n}\n\nasync function prepareForDiff(app1: App, app2: App) {\n\tconst id = Math.random().toString(36).slice(2)\n\tconst app1CopyPath = path.join(\n\t\tdiffTmpDir,\n\t\tpath.basename(getWorkshopRoot()),\n\t\tapp1.name,\n\t\tid,\n\t)\n\tconst app2CopyPath = path.join(\n\t\tdiffTmpDir,\n\t\tpath.basename(getWorkshopRoot()),\n\t\tapp2.name,\n\t\tid,\n\t)\n\t// if everything except the `name` property of the `package.json` is the same\n\t// the don't bother copying it\n\tconst comparePkgJson = (pkg1: any, pkg2: any) => {\n\t\tconst { name, ...rest1 } = pkg1\n\t\tconst { name: name2, ...rest2 } = pkg2\n\t\treturn JSON.stringify(rest1) === JSON.stringify(rest2)\n\t}\n\tconst app1PkgJson =\n\t\tapp1.dev.type === 'script'\n\t\t\t? await fsExtra\n\t\t\t\t\t.readJSON(path.join(app1.fullPath, 'package.json'))\n\t\t\t\t\t.catch(() => ({}))\n\t\t\t: {}\n\tconst app2PkgJson =\n\t\tapp1.dev.type === 'script'\n\t\t\t? await fsExtra\n\t\t\t\t\t.readJSON(path.join(app2.fullPath, 'package.json'))\n\t\t\t\t\t.catch(() => ({}))\n\t\t\t: {}\n\tconst pkgJsonIgnore: Array<string> = comparePkgJson(app1PkgJson, app2PkgJson)\n\t\t? ['package.json']\n\t\t: []\n\tconst workshopIgnore = [\n\t\t...(await getDiffIgnore(path.join(getWorkshopRoot(), '.gitignore'))),\n\t\t...(await getDiffIgnore(\n\t\t\tpath.join(getWorkshopRoot(), 'epicshop', '.diffignore'),\n\t\t)),\n\t]\n\n\tawait Promise.all([\n\t\tcopyUnignoredFiles(app1.fullPath, app1CopyPath, [\n\t\t\t...DEFAULT_IGNORE_PATTERNS,\n\t\t\t...pkgJsonIgnore,\n\t\t\t...workshopIgnore,\n\t\t\t...(await getDiffIgnore(path.join(app1.fullPath, '.gitignore'))),\n\t\t\t...(await getDiffIgnore(\n\t\t\t\tpath.join(app1.fullPath, 'epicshop', '.diffignore'),\n\t\t\t)),\n\t\t]),\n\t\tcopyUnignoredFiles(app2.fullPath, app2CopyPath, [\n\t\t\t...DEFAULT_IGNORE_PATTERNS,\n\t\t\t...pkgJsonIgnore,\n\t\t\t...workshopIgnore,\n\t\t\t...(await getDiffIgnore(path.join(app2.fullPath, '.gitignore'))),\n\t\t\t...(await getDiffIgnore(\n\t\t\t\tpath.join(app2.fullPath, 'epicshop', '.diffignore'),\n\t\t\t)),\n\t\t]),\n\t])\n\n\treturn { app1CopyPath, app2CopyPath }\n}\n\nasync function getDiffIgnore(filePath: string): Promise<Array<string>> {\n\treturn (await fsExtra.pathExists(filePath))\n\t\t? fsExtra.readFile(filePath, 'utf8').then((content) =>\n\t\t\t\tcontent\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((line) => line.trim())\n\t\t\t\t\t.filter((line) => !line.startsWith('#'))\n\t\t\t\t\t.filter(Boolean),\n\t\t\t)\n\t\t: []\n}\n\nasync function getForceFreshForDiff(\n\tapp1: App,\n\tapp2: App,\n\tcacheEntry:\n\t\t| CacheEntry\n\t\t| null\n\t\t| undefined\n\t\t| Promise<CacheEntry | null | undefined>,\n) {\n\t// don't know when the cache was created? force refresh\n\tconst resolvedCacheEntry = await cacheEntry\n\tconst cacheModified = resolvedCacheEntry?.metadata.createdTime\n\tif (!cacheModified) return true\n\n\t// app1 modified after cache? force refresh\n\tconst app1Modified = modifiedTimes.get(app1.fullPath) ?? 0\n\tif (app1Modified > cacheModified) return true\n\n\t// app2 modified after cache? force refresh\n\tconst app2Modified = modifiedTimes.get(app2.fullPath) ?? 0\n\tif (app2Modified > cacheModified) return true\n\n\t// ok, now let's actually check the modified times of all files in the\n\t// directories and as soon as we find a file that was modified more recently\n\t// then we know we need to force refresh\n\tconst modifiedMoreRecently = await modifiedMoreRecentlyThan(\n\t\tcacheModified,\n\t\tapp1.fullPath,\n\t\tapp2.fullPath,\n\t)\n\tif (modifiedMoreRecently) return true\n\n\treturn undefined\n}\n\nexport async function getDiffFiles(\n\tapp1: App,\n\tapp2: App,\n\t{\n\t\tforceFresh,\n\t\ttimings,\n\t\trequest,\n\t}: { forceFresh?: boolean; timings?: Timings; request?: Request } = {},\n) {\n\tconst key = `${app1.relativePath}__vs__${app2.relativePath}`\n\tconst cacheEntry = await diffFilesCache.get(key)\n\tconst result = await cachified({\n\t\tkey,\n\t\tcache: diffFilesCache,\n\t\tforceFresh:\n\t\t\tforceFresh || (await getForceFreshForDiff(app1, app2, cacheEntry)),\n\t\ttimings,\n\t\trequest,\n\t\tgetFreshValue: () => getDiffFilesImpl(app1, app2),\n\t})\n\treturn result\n}\n\nfunction getAppTestFiles(app: App) {\n\treturn app.test.type === 'browser' ? app.test.testFiles : []\n}\n\nasync function getDiffFilesImpl(app1: App, app2: App) {\n\tif (app1.name === app2.name) {\n\t\treturn []\n\t}\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath)\n\tvoid fsExtra.remove(app2CopyPath)\n\n\tconst typesMap = {\n\t\tChangedFile: 'modified',\n\t\tAddedFile: 'added',\n\t\tDeletedFile: 'deleted',\n\t\tRenamedFile: 'renamed',\n\t}\n\n\tconst parsed = parseGitDiff(diffOutput, { noPrefix: true })\n\n\tconst testFiles = Array.from(\n\t\tnew Set([...getAppTestFiles(app1), ...getAppTestFiles(app2)]),\n\t)\n\n\tconst startLine = (file: AnyFileChange) => {\n\t\tconst chunk = file.type === 'ChangedFile' && file.chunks[0]\n\t\tif (chunk) {\n\t\t\treturn chunk.type === 'Chunk'\n\t\t\t\t? chunk.fromFileRange.start\n\t\t\t\t: chunk.type === 'CombinedChunk'\n\t\t\t\t\t? chunk.fromFileRangeA.start\n\t\t\t\t\t: 1\n\t\t}\n\t\treturn 1\n\t}\n\n\treturn parsed.files\n\t\t.map((file) => ({\n\t\t\t// prettier-ignore\n\n\t\t\tstatus: (typesMap[file.type] ?? 'unknown') as 'renamed' | 'modified' | 'deleted' | 'added' | 'unknown',\n\t\t\tpath: diffPathToRelative(\n\t\t\t\tfile.type === 'RenamedFile' ? file.pathBefore : file.path,\n\t\t\t),\n\t\t\tline: startLine(file),\n\t\t}))\n\t\t.filter((file) => !testFiles.includes(file.path))\n}\n\nexport async function getDiffCode(\n\tapp1: App,\n\tapp2: App,\n\t{\n\t\tforceFresh,\n\t\ttimings,\n\t\trequest,\n\t}: { forceFresh?: boolean; timings?: Timings; request?: Request } = {},\n) {\n\tconst key = `${app1.relativePath}__vs__${app2.relativePath}`\n\tconst cacheEntry = await diffCodeCache.get(key)\n\tconst result = await cachified({\n\t\tkey,\n\t\tcache: diffCodeCache,\n\t\tforceFresh:\n\t\t\tforceFresh || (await getForceFreshForDiff(app1, app2, cacheEntry)),\n\t\ttimings,\n\t\trequest,\n\t\tgetFreshValue: () => getDiffCodeImpl(app1, app2),\n\t})\n\treturn result\n}\n\nasync function getDiffCodeImpl(app1: App, app2: App) {\n\tconst markdownLines = ['']\n\n\tif (app1.name === app2.name) {\n\t\tmarkdownLines.push(\n\t\t\t'<p className=\"p-4 text-center\">You are comparing the same app</p>',\n\t\t)\n\t\tconst code = await compileMarkdownString(markdownLines.join('\\n'))\n\t\treturn code\n\t}\n\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t\t'--color=never',\n\t\t\t'--color-moved-ws=allow-indentation-change',\n\t\t\t'--no-prefix',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath)\n\tvoid fsExtra.remove(app2CopyPath)\n\n\tconst parsed = parseGitDiff(diffOutput)\n\n\tif (!parsed.files.length) {\n\t\tmarkdownLines.push(\n\t\t\t'<div className=\"m-5 inline-flex items-center justify-center bg-foreground px-1 py-0.5 font-mono text-sm uppercase text-background\">No changes</div>',\n\t\t)\n\t}\n\n\tconst app1TestFiles = getAppTestFiles(app1)\n\tconst app2TestFiles = getAppTestFiles(app2)\n\n\tfor (const file of parsed.files) {\n\t\tconst pathToCopy = file.type === 'RenamedFile' ? file.pathBefore : file.path\n\t\tconst relativePath = diffPathToRelative(pathToCopy)\n\t\tif (app1TestFiles.includes(relativePath)) continue\n\t\tconst filePathApp1 = path.join(app1.fullPath, relativePath)\n\n\t\tconst pathToApp2 = file.type === 'RenamedFile' ? file.pathAfter : file.path\n\t\tconst relativePathApp2 = diffPathToRelative(pathToApp2)\n\t\tif (app2TestFiles.includes(relativePathApp2)) continue\n\t\tconst filePathApp2 = path.join(app2.fullPath, relativePathApp2)\n\n\t\tswitch (file.type) {\n\t\t\tcase 'ChangedFile': {\n\t\t\t\tmarkdownLines.push(`\n\n<Accordion title=${JSON.stringify(relativePath)} variant=\"changed\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'DeletedFile': {\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${JSON.stringify(relativePath)} variant=\"deleted\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'RenamedFile': {\n\t\t\t\tconst relativeBefore = diffPathToRelative(file.pathBefore)\n\t\t\t\tconst relativeAfter = diffPathToRelative(file.pathAfter)\n\t\t\t\tconst title = JSON.stringify(`${relativeBefore} ▶️ ${relativeAfter}`)\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${title} variant=\"renamed\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'AddedFile': {\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${JSON.stringify(relativePath)} variant=\"added\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(file)\n\t\t\t\tthrow new Error(`Unknown file type: ${file}`)\n\t\t\t}\n\t\t}\n\t}\n\tconst code = await compileMarkdownString(markdownLines.join('\\n'))\n\treturn code\n}\n\nexport async function getDiffOutputWithRelativePaths(app1: App, app2: App) {\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t\t'--color=never',\n\t\t\t'--color-moved-ws=allow-indentation-change',\n\t\t\t'--no-prefix',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath)\n\tvoid fsExtra.remove(app2CopyPath)\n\n\treturn diffOutput\n\t\t.replaceAll(app1CopyPath.slice(1), '.')\n\t\t.replaceAll(app2CopyPath.slice(1), '.')\n}\n"]}
|
|
1
|
+
{"version":3,"file":"diff.server.js","sourceRoot":"","sources":["../../src/diff.server.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { getEnv } from './init-env.js'\n\nimport os from 'os'\nimport path from 'path'\nimport { type CacheEntry } from '@epic-web/cachified'\nimport { execa } from 'execa'\nimport fsExtra from 'fs-extra'\nimport ignore from 'ignore'\nimport parseGitDiff, { type AnyFileChange } from 'parse-git-diff'\nimport { bundledLanguagesInfo } from 'shiki/langs'\nimport {\n\tgetForceFreshForDir,\n\tgetRelativePath,\n\tgetWorkshopRoot,\n\tmodifiedTimes,\n\ttype App,\n} from './apps.server.js'\nimport {\n\tcachified,\n\tcopyUnignoredFilesCache,\n\tdiffCodeCache,\n\tdiffFilesCache,\n} from './cache.server.js'\nimport { compileMarkdownString } from './compile-mdx.server.js'\nimport { modifiedMoreRecentlyThan } from './modified-time.server.js'\nimport { type Timings } from './timing.server.js'\n\nconst epicshopTempDir = path.join(os.tmpdir(), 'epicshop')\n\nconst isDeployed = getEnv().EPICSHOP_DEPLOYED\n\nconst diffTmpDir = path.join(epicshopTempDir, 'diff')\n\n/**\n * Converts a diff file path to a relative path for display and lookup.\n * - Removes leading/trailing quotes.\n * - Strips diff prefixes like a/, b/, .\\a\\, .\\b\\, ./a/, ./b/ (for both POSIX and Windows).\n * - Normalizes the path separators.\n * - Removes the diff temp directory prefix and splits out the actual relative path.\n */\nfunction diffPathToRelative(filePath: string) {\n\tlet normalizedPath = path.normalize(\n\t\tfilePath\n\t\t\t.replace(/^[\"']|[\"']$/g, '')\n\t\t\t.replace(/^(\\.\\\\[ab]\\\\|\\.\\/[ab]\\/|[ab][\\\\/])/, ''),\n\t)\n\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tconst [workshopRootDirname, appId, id, ...relativePath] = normalizedPath\n\t\t.replace(\n\t\t\tprocess.platform === 'win32' || normalizedPath.startsWith(path.sep)\n\t\t\t\t? `${diffTmpDir}${path.sep}`\n\t\t\t\t: `${diffTmpDir.slice(1)}${path.sep}`,\n\t\t\t'',\n\t\t)\n\t\t.split(path.sep)\n\n\treturn relativePath.join(path.sep)\n}\n\nfunction getLanguage(ext: string) {\n\treturn (\n\t\tbundledLanguagesInfo.find((l) => l.id === ext || l.aliases?.includes(ext))\n\t\t\t?.id ?? 'text'\n\t)\n}\n\nfunction getFileCodeblocks(\n\tfile: ReturnType<typeof parseGitDiff>['files'][number],\n\tfilePathApp1: string,\n\tfilePathApp2: string,\n\ttype: string,\n) {\n\tif (!file.chunks.length) {\n\t\treturn [\n\t\t\t`<p className=\"m-0 p-4 border-b text-muted-foreground\">No changes</p>`,\n\t\t]\n\t}\n\tconst filepath = diffPathToRelative(\n\t\tfile.type === 'RenamedFile' ? file.pathAfter : file.path,\n\t)\n\tconst extension = path.extname(filepath).slice(1)\n\tconst lang = getLanguage(extension)\n\tconst pathToCopy = file.type === 'RenamedFile' ? file.pathBefore : file.path\n\tconst relativePath = diffPathToRelative(pathToCopy)\n\tconst markdownLines = []\n\tfor (const chunk of file.chunks) {\n\t\tconst removedLineNumbers = []\n\t\tconst addedLineNumbers = []\n\t\tconst lines = []\n\t\tlet toStartLine = 0\n\t\tlet startLine = 1\n\t\tif (chunk.type === 'BinaryFilesChunk') {\n\t\t\tlines.push(\n\t\t\t\ttype === 'AddedFile'\n\t\t\t\t\t? `Binary file added`\n\t\t\t\t\t: type === 'DeletedFile'\n\t\t\t\t\t\t? 'Binary file deleted'\n\t\t\t\t\t\t: 'Binary file changed',\n\t\t\t)\n\t\t} else {\n\t\t\tstartLine =\n\t\t\t\tchunk.type === 'Chunk'\n\t\t\t\t\t? chunk.fromFileRange.start\n\t\t\t\t\t: chunk.type === 'CombinedChunk'\n\t\t\t\t\t\t? chunk.fromFileRangeA.start\n\t\t\t\t\t\t: 1\n\t\t\ttoStartLine = chunk.toFileRange.start\n\t\t\tfor (\n\t\t\t\tlet lineNumber = 0;\n\t\t\t\tlineNumber < chunk.changes.length;\n\t\t\t\tlineNumber++\n\t\t\t) {\n\t\t\t\tconst change = chunk.changes[lineNumber]\n\t\t\t\tif (!change) continue\n\t\t\t\tlines.push(change.content)\n\t\t\t\tswitch (change.type) {\n\t\t\t\t\tcase 'AddedLine': {\n\t\t\t\t\t\taddedLineNumbers.push(startLine + lineNumber)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'DeletedLine': {\n\t\t\t\t\t\tremovedLineNumbers.push(startLine + lineNumber)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst params = [\n\t\t\t['filename', relativePath.replace(/\\\\/g, '\\\\\\\\')],\n\t\t\t['start', startLine.toString()],\n\t\t\tremovedLineNumbers.length\n\t\t\t\t? ['remove', removedLineNumbers.join(',')]\n\t\t\t\t: null,\n\t\t\taddedLineNumbers.length ? ['add', addedLineNumbers.join(',')] : null,\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.map(([key, value]) => `${key}=${value}`)\n\t\t\t.join(' ')\n\n\t\tconst launchEditorClassName =\n\t\t\t'border hover:bg-foreground/20 rounded px-2 py-0.5 font-mono text-xs font-semibold'\n\n\t\tfunction launchEditor(appNum: number, line: number) {\n\t\t\tline ||= 1 // handle 0\n\t\t\tif (isDeployed) {\n\t\t\t\tif (type === 'DeletedFile' && appNum === 2) return ''\n\t\t\t\tif (type === 'AddedFile' && appNum === 1) return ''\n\t\t\t}\n\n\t\t\tconst label =\n\t\t\t\t(type === 'AddedFile' && appNum === 1) ||\n\t\t\t\t(type === 'DeletedFile' && appNum === 2)\n\t\t\t\t\t? `CREATE in APP ${appNum}`\n\t\t\t\t\t: `OPEN in APP ${appNum}`\n\t\t\tconst file = JSON.stringify(appNum === 1 ? filePathApp1 : filePathApp2)\n\t\t\tconst fixedTitle = getRelativePath(file)\n\n\t\t\treturn `\n<LaunchEditor file=${file} line={${line}}>\n\t<span title=\"${fixedTitle}\" className=\"${launchEditorClassName}\">${label}</span>\n</LaunchEditor>`\n\t\t}\n\n\t\tmarkdownLines.push(`\n<div className=\"relative\">\n\n\\`\\`\\`${lang} ${params}\n${lines.join('\\n')}\n\\`\\`\\`\n\n<div className=\"flex gap-4 absolute top-1 right-3 items-center\">\n\t${launchEditor(1, startLine)}\n\t<div className=\"display-alt-down flex gap-2\">\n\t\t<LaunchEditor file=${JSON.stringify(\n\t\t\tfilePathApp1,\n\t\t)} syncTo={{file: ${JSON.stringify(filePathApp2)}}}>\n\t\t\t<span className=\"block ${launchEditorClassName}\">\n\t\t\t\t<Icon name=\"ArrowLeft\" title=\"Copy app 2 file to app 1\" />\n\t\t\t</span>\n\t\t</LaunchEditor>\n\t\t<LaunchEditor file=${JSON.stringify(\n\t\t\tfilePathApp2,\n\t\t)} syncTo={{file: ${JSON.stringify(filePathApp1)}}}>\n\t\t\t<span className=\"block ${launchEditorClassName}\">\n\t\t\t\t<Icon name=\"ArrowRight\" title=\"Copy app 1 file to app 2\" />\n\t\t\t</span>\n\t\t</LaunchEditor>\n\t</div>\n\t${launchEditor(2, toStartLine)}\n</div>\n\n</div>\n`)\n\t}\n\treturn markdownLines\n}\n\nconst DEFAULT_IGNORE_PATTERNS = [\n\t'**/README.*',\n\t'**/package-lock.json',\n\t'**/.DS_Store',\n\t'**/.vscode',\n\t'**/.idea',\n\t'**/.git',\n\t'**/*.db',\n\t'**/epicshop/**',\n]\n\nasync function copyUnignoredFiles(\n\tsrcDir: string,\n\tdestDir: string,\n\tignoreList: Array<string>,\n) {\n\tconst key = `COPY_${srcDir}__${destDir}__${ignoreList.join('_')}`\n\tawait cachified({\n\t\tkey,\n\t\tcache: copyUnignoredFilesCache,\n\t\tforceFresh: await getForceFreshForDir(\n\t\t\tcopyUnignoredFilesCache.get(key),\n\t\t\tsrcDir,\n\t\t),\n\t\tasync getFreshValue() {\n\t\t\t// @ts-ignore 🤷♂️ weird module stuff\n\t\t\tconst ig = ignore().add(ignoreList)\n\n\t\t\tawait fsExtra.remove(destDir)\n\t\t\tawait fsExtra.copy(srcDir, destDir, {\n\t\t\t\tfilter: async (file) => {\n\t\t\t\t\tif (file === srcDir) return true\n\t\t\t\t\treturn !ig.ignores(path.relative(srcDir, file))\n\t\t\t\t},\n\t\t\t})\n\t\t},\n\t})\n}\n\nasync function prepareForDiff(app1: App, app2: App) {\n\tconst id = Math.random().toString(36).slice(2)\n\tconst app1CopyPath = path.join(\n\t\tdiffTmpDir,\n\t\tpath.basename(getWorkshopRoot()),\n\t\tapp1.name,\n\t\tid,\n\t)\n\tconst app2CopyPath = path.join(\n\t\tdiffTmpDir,\n\t\tpath.basename(getWorkshopRoot()),\n\t\tapp2.name,\n\t\tid,\n\t)\n\t// if everything except the `name` property of the `package.json` is the same\n\t// the don't bother copying it\n\tconst comparePkgJson = (pkg1: any, pkg2: any) => {\n\t\tconst { name, ...rest1 } = pkg1\n\t\tconst { name: name2, ...rest2 } = pkg2\n\t\treturn JSON.stringify(rest1) === JSON.stringify(rest2)\n\t}\n\tconst app1PkgJson =\n\t\tapp1.dev.type === 'script'\n\t\t\t? await fsExtra\n\t\t\t\t\t.readJSON(path.join(app1.fullPath, 'package.json'))\n\t\t\t\t\t.catch(() => ({}))\n\t\t\t: {}\n\tconst app2PkgJson =\n\t\tapp1.dev.type === 'script'\n\t\t\t? await fsExtra\n\t\t\t\t\t.readJSON(path.join(app2.fullPath, 'package.json'))\n\t\t\t\t\t.catch(() => ({}))\n\t\t\t: {}\n\tconst pkgJsonIgnore: Array<string> = comparePkgJson(app1PkgJson, app2PkgJson)\n\t\t? ['package.json']\n\t\t: []\n\tconst workshopIgnore = [\n\t\t...(await getDiffIgnore(path.join(getWorkshopRoot(), '.gitignore'))),\n\t\t...(await getDiffIgnore(\n\t\t\tpath.join(getWorkshopRoot(), 'epicshop', '.diffignore'),\n\t\t)),\n\t]\n\n\tawait Promise.all([\n\t\tcopyUnignoredFiles(app1.fullPath, app1CopyPath, [\n\t\t\t...DEFAULT_IGNORE_PATTERNS,\n\t\t\t...pkgJsonIgnore,\n\t\t\t...workshopIgnore,\n\t\t\t...(await getDiffIgnore(path.join(app1.fullPath, '.gitignore'))),\n\t\t\t...(await getDiffIgnore(\n\t\t\t\tpath.join(app1.fullPath, 'epicshop', '.diffignore'),\n\t\t\t)),\n\t\t]),\n\t\tcopyUnignoredFiles(app2.fullPath, app2CopyPath, [\n\t\t\t...DEFAULT_IGNORE_PATTERNS,\n\t\t\t...pkgJsonIgnore,\n\t\t\t...workshopIgnore,\n\t\t\t...(await getDiffIgnore(path.join(app2.fullPath, '.gitignore'))),\n\t\t\t...(await getDiffIgnore(\n\t\t\t\tpath.join(app2.fullPath, 'epicshop', '.diffignore'),\n\t\t\t)),\n\t\t]),\n\t])\n\n\treturn { app1CopyPath, app2CopyPath }\n}\n\nasync function getDiffIgnore(filePath: string): Promise<Array<string>> {\n\treturn (await fsExtra.pathExists(filePath))\n\t\t? fsExtra.readFile(filePath, 'utf8').then((content) =>\n\t\t\t\tcontent\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((line) => line.trim())\n\t\t\t\t\t.filter((line) => !line.startsWith('#'))\n\t\t\t\t\t.filter(Boolean),\n\t\t\t)\n\t\t: []\n}\n\nasync function getForceFreshForDiff(\n\tapp1: App,\n\tapp2: App,\n\tcacheEntry:\n\t\t| CacheEntry\n\t\t| null\n\t\t| undefined\n\t\t| Promise<CacheEntry | null | undefined>,\n) {\n\t// don't know when the cache was created? force refresh\n\tconst resolvedCacheEntry = await cacheEntry\n\tconst cacheModified = resolvedCacheEntry?.metadata.createdTime\n\tif (!cacheModified) return true\n\n\t// app1 modified after cache? force refresh\n\tconst app1Modified = modifiedTimes.get(app1.fullPath) ?? 0\n\tif (app1Modified > cacheModified) return true\n\n\t// app2 modified after cache? force refresh\n\tconst app2Modified = modifiedTimes.get(app2.fullPath) ?? 0\n\tif (app2Modified > cacheModified) return true\n\n\t// ok, now let's actually check the modified times of all files in the\n\t// directories and as soon as we find a file that was modified more recently\n\t// then we know we need to force refresh\n\tconst modifiedMoreRecently = await modifiedMoreRecentlyThan(\n\t\tcacheModified,\n\t\tapp1.fullPath,\n\t\tapp2.fullPath,\n\t)\n\tif (modifiedMoreRecently) return true\n\n\treturn undefined\n}\n\nexport async function getDiffFiles(\n\tapp1: App,\n\tapp2: App,\n\t{\n\t\tforceFresh,\n\t\ttimings,\n\t\trequest,\n\t}: { forceFresh?: boolean; timings?: Timings; request?: Request } = {},\n) {\n\tconst key = `${app1.relativePath}__vs__${app2.relativePath}`\n\tconst cacheEntry = await diffFilesCache.get(key)\n\tconst result = await cachified({\n\t\tkey,\n\t\tcache: diffFilesCache,\n\t\tforceFresh:\n\t\t\tforceFresh || (await getForceFreshForDiff(app1, app2, cacheEntry)),\n\t\ttimings,\n\t\trequest,\n\t\tgetFreshValue: () => getDiffFilesImpl(app1, app2),\n\t})\n\treturn result\n}\n\nfunction getAppTestFiles(app: App) {\n\treturn app.test.type === 'browser' ? app.test.testFiles : []\n}\n\nasync function getDiffFilesImpl(app1: App, app2: App) {\n\tif (app1.name === app2.name) {\n\t\treturn []\n\t}\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath).catch(() => {})\n\tvoid fsExtra.remove(app2CopyPath).catch(() => {})\n\n\tconst typesMap = {\n\t\tChangedFile: 'modified',\n\t\tAddedFile: 'added',\n\t\tDeletedFile: 'deleted',\n\t\tRenamedFile: 'renamed',\n\t}\n\n\tconst parsed = parseGitDiff(diffOutput, { noPrefix: true })\n\n\tconst testFiles = Array.from(\n\t\tnew Set([...getAppTestFiles(app1), ...getAppTestFiles(app2)]),\n\t)\n\n\tconst startLine = (file: AnyFileChange) => {\n\t\tconst chunk = file.type === 'ChangedFile' && file.chunks[0]\n\t\tif (chunk) {\n\t\t\treturn chunk.type === 'Chunk'\n\t\t\t\t? chunk.fromFileRange.start\n\t\t\t\t: chunk.type === 'CombinedChunk'\n\t\t\t\t\t? chunk.fromFileRangeA.start\n\t\t\t\t\t: 1\n\t\t}\n\t\treturn 1\n\t}\n\n\treturn parsed.files\n\t\t.map((file) => ({\n\t\t\t// prettier-ignore\n\n\t\t\tstatus: (typesMap[file.type] ?? 'unknown') as 'renamed' | 'modified' | 'deleted' | 'added' | 'unknown',\n\t\t\tpath: diffPathToRelative(\n\t\t\t\tfile.type === 'RenamedFile' ? file.pathBefore : file.path,\n\t\t\t),\n\t\t\tline: startLine(file),\n\t\t}))\n\t\t.filter((file) => !testFiles.includes(file.path))\n}\n\nexport async function getDiffCode(\n\tapp1: App,\n\tapp2: App,\n\t{\n\t\tforceFresh,\n\t\ttimings,\n\t\trequest,\n\t}: { forceFresh?: boolean; timings?: Timings; request?: Request } = {},\n) {\n\tconst key = `${app1.relativePath}__vs__${app2.relativePath}`\n\tconst cacheEntry = await diffCodeCache.get(key)\n\tconst result = await cachified({\n\t\tkey,\n\t\tcache: diffCodeCache,\n\t\tforceFresh:\n\t\t\tforceFresh || (await getForceFreshForDiff(app1, app2, cacheEntry)),\n\t\ttimings,\n\t\trequest,\n\t\tgetFreshValue: () => getDiffCodeImpl(app1, app2),\n\t})\n\treturn result\n}\n\nasync function getDiffCodeImpl(app1: App, app2: App) {\n\tconst markdownLines = ['']\n\n\tif (app1.name === app2.name) {\n\t\tmarkdownLines.push(\n\t\t\t'<p className=\"p-4 text-center\">You are comparing the same app</p>',\n\t\t)\n\t\tconst code = await compileMarkdownString(markdownLines.join('\\n'))\n\t\treturn code\n\t}\n\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t\t'--color=never',\n\t\t\t'--color-moved-ws=allow-indentation-change',\n\t\t\t'--no-prefix',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath).catch(() => {})\n\tvoid fsExtra.remove(app2CopyPath).catch(() => {})\n\n\tconst parsed = parseGitDiff(diffOutput)\n\n\tif (!parsed.files.length) {\n\t\tmarkdownLines.push(\n\t\t\t'<div className=\"m-5 inline-flex items-center justify-center bg-foreground px-1 py-0.5 font-mono text-sm uppercase text-background\">No changes</div>',\n\t\t)\n\t}\n\n\tconst app1TestFiles = getAppTestFiles(app1)\n\tconst app2TestFiles = getAppTestFiles(app2)\n\n\tfor (const file of parsed.files) {\n\t\tconst pathToCopy = file.type === 'RenamedFile' ? file.pathBefore : file.path\n\t\tconst relativePath = diffPathToRelative(pathToCopy)\n\t\tif (app1TestFiles.includes(relativePath)) continue\n\t\tconst filePathApp1 = path.join(app1.fullPath, relativePath)\n\n\t\tconst pathToApp2 = file.type === 'RenamedFile' ? file.pathAfter : file.path\n\t\tconst relativePathApp2 = diffPathToRelative(pathToApp2)\n\t\tif (app2TestFiles.includes(relativePathApp2)) continue\n\t\tconst filePathApp2 = path.join(app2.fullPath, relativePathApp2)\n\n\t\tswitch (file.type) {\n\t\t\tcase 'ChangedFile': {\n\t\t\t\tmarkdownLines.push(`\n\n<Accordion title=${JSON.stringify(relativePath)} variant=\"changed\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'DeletedFile': {\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${JSON.stringify(relativePath)} variant=\"deleted\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'RenamedFile': {\n\t\t\t\tconst relativeBefore = diffPathToRelative(file.pathBefore)\n\t\t\t\tconst relativeAfter = diffPathToRelative(file.pathAfter)\n\t\t\t\tconst title = JSON.stringify(`${relativeBefore} ▶️ ${relativeAfter}`)\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${title} variant=\"renamed\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'AddedFile': {\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${JSON.stringify(relativePath)} variant=\"added\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(file)\n\t\t\t\tthrow new Error(`Unknown file type: ${file}`)\n\t\t\t}\n\t\t}\n\t}\n\tconst code = await compileMarkdownString(markdownLines.join('\\n'))\n\treturn code\n}\n\nexport async function getDiffOutputWithRelativePaths(app1: App, app2: App) {\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t\t'--color=never',\n\t\t\t'--color-moved-ws=allow-indentation-change',\n\t\t\t'--no-prefix',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath).catch(() => {})\n\tvoid fsExtra.remove(app2CopyPath).catch(() => {})\n\n\treturn diffOutput\n\t\t.replaceAll(app1CopyPath.slice(1), '.')\n\t\t.replaceAll(app2CopyPath.slice(1), '.')\n}\n"]}
|