import assert from 'node:assert';
import childProcess from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
import {
git,
localRepoPath,
makeTmpDir,
npm,
writeGeneratedFile,
} from './utils.js';
const LOCAL = 'local';
const { tmpDirPath } = makeTmpDir('graphql-js-npm-diff');
const args = process.argv.slice(2);
let [fromRevision, toRevision] = args;
if (args.length < 2) {
fromRevision ??= 'HEAD';
toRevision ??= LOCAL;
console.warn(
`Assuming you meant: diff-npm-package ${fromRevision} ${toRevision}`,
);
}
console.log(`📦 Building NPM package for ${fromRevision}...`);
const fromPackage = prepareNPMPackage(fromRevision);
console.log(`📦 Building NPM package for ${toRevision}...`);
const toPackage = prepareNPMPackage(toRevision);
console.log('âž–âž• Generating diff...');
const diff = npm().diff('--diff', fromPackage, '--diff', toPackage);
if (diff === '') {
console.log('No changes found!');
} else {
const reportPath = localRepoPath('reports', 'npm-dist-diff.html');
writeGeneratedFile(reportPath, generateReport(diff));
console.log('Report saved to: ', reportPath);
}
function generateReport(diffString: string): string {
return `
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8" />
<!-- Make sure to load the highlight.js CSS file before the Diff2Html CSS file -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.1/styles/github.min.css" />
<link
rel="stylesheet"
type="text/css"
href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css"
/>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>
</head>
<script>
const diffString = ${JSON.stringify(diffString)};
document.addEventListener('DOMContentLoaded', () => {
const targetElement = document.getElementById('myDiffElement');
const configuration = {
drawFileList: true,
fileContentToggle: true,
matching: 'lines',
outputFormat: 'side-by-side',
renderNothingWhenEmpty: false,
};
const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);
diff2htmlUi.draw();
diff2htmlUi.highlightCode();
});
</script>
<body>
<div id="myDiffElement"></div>
</body>
</html>
`;
}
function prepareNPMPackage(revision: string): string {
if (revision === LOCAL) {
npm({ cwd: localRepoPath(), quiet: true }).run('build:npm');
return localRepoPath('npmDist');
}
const hash = git().revParse(revision);
assert(hash != null);
const repoDir = tmpDirPath(hash);
fs.rmSync(repoDir, { recursive: true, force: true });
fs.mkdirSync(repoDir);
childProcess.execSync(`git archive "${hash}" | tar -xC "${repoDir}"`);
npm({ cwd: repoDir, quiet: true }).ci('--ignore-scripts');
npm({ cwd: repoDir, quiet: true }).run('build:npm');
return path.join(repoDir, 'npmDist');
}