Files
ForgeFlow/scripts/generate-source-manifest.mjs
T

38 lines
1.8 KiB
JavaScript

import { createHash } from 'node:crypto';
import { readdir, readFile, stat, writeFile } from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const excludedDirectories = new Set(['.git', '.forgeflow', 'artifacts', 'coverage', 'dist', 'node_modules', 'playwright-report', 'ForgeFlow-runtime-win-x64']);
const excludedFiles = new Set(['SOURCE_MANIFEST.txt']);
async function collect(directory, output = []) {
for (const entry of await readdir(directory, { withFileTypes: true })) {
if (excludedDirectories.has(entry.name)) continue;
const absolute = path.join(directory, entry.name);
if (entry.isDirectory()) await collect(absolute, output);
else if (!excludedFiles.has(entry.name)) output.push(absolute);
}
return output;
}
const packageJson = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8'));
const files = (await collect(root)).sort((left, right) => left.localeCompare(right, 'en'));
const lines = [
`ForgeFlow ${packageJson.version} source manifest`,
'SHA-256 BYTES PATH',
'(The manifest excludes itself, dependencies and generated release artifacts.)'
];
for (const absolute of files) {
const bytes = await readFile(absolute);
const size = (await stat(absolute)).size;
const digest = createHash('sha256').update(bytes).digest('hex');
const relative = path.relative(root, absolute).replaceAll('\\', '/');
lines.push(`${digest} ${String(size).padStart(12)} ${relative}`);
}
await writeFile(path.join(root, 'SOURCE_MANIFEST.txt'), `${lines.join('\n')}\n`, 'utf8');
console.log(`Wrote ${files.length} entries for ForgeFlow ${packageJson.version}.`);