mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
69 lines
2.3 KiB
JavaScript
69 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
// Splits a jscpd JSON report's `duplicates` array into N bucket files so a
|
|
// caller can download and sample one small file instead of the whole report
|
|
// (which can run into tens of MB on a large monorepo). Round-robin, not
|
|
// contiguous chunks, so a run of similarly-sized clusters in scan order
|
|
// doesn't pile up in one bucket.
|
|
|
|
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
|
|
export function splitDuplicates(duplicates, bucketCount) {
|
|
const buckets = Array.from({ length: bucketCount }, () => []);
|
|
duplicates.forEach((dup, i) => buckets[i % bucketCount].push(dup));
|
|
return buckets;
|
|
}
|
|
|
|
export function writeBuckets(buckets, outputDir, deps = {}) {
|
|
const mkdirImpl = deps.mkdir ?? mkdirSync;
|
|
const writeImpl = deps.write ?? writeFileSync;
|
|
mkdirImpl(outputDir, { recursive: true });
|
|
return buckets.map((duplicates, i) => {
|
|
const path = join(outputDir, `bucket-${i}.json`);
|
|
writeImpl(path, JSON.stringify({ duplicates }));
|
|
return path;
|
|
});
|
|
}
|
|
|
|
export function parseBucketCount(raw) {
|
|
const count = Number(raw ?? 20);
|
|
if (!Number.isInteger(count) || count <= 0) {
|
|
throw new Error(`BUCKET_COUNT must be a positive integer, got '${raw}'`);
|
|
}
|
|
return count;
|
|
}
|
|
|
|
export function loadDuplicates(reportPath, deps = {}) {
|
|
const readImpl = deps.read ?? readFileSync;
|
|
const report = JSON.parse(readImpl(reportPath, 'utf8'));
|
|
if (!Array.isArray(report.duplicates)) {
|
|
throw new Error('report.duplicates must be an array');
|
|
}
|
|
return report.duplicates;
|
|
}
|
|
|
|
// Exits non-zero on any failure. The workflow step already runs with
|
|
// continue-on-error, so this can't fail the job — it only stops a broken
|
|
// split (zero buckets written) from reporting success.
|
|
function main() {
|
|
const reportPath = process.env.REPORT_PATH;
|
|
const outputDir = process.env.OUTPUT_DIR;
|
|
if (!reportPath || !outputDir) {
|
|
process.stderr.write('split-jscpd-report: REPORT_PATH and OUTPUT_DIR are required\n');
|
|
process.exit(1);
|
|
}
|
|
try {
|
|
const bucketCount = parseBucketCount(process.env.BUCKET_COUNT);
|
|
const duplicates = loadDuplicates(reportPath);
|
|
const buckets = splitDuplicates(duplicates, bucketCount);
|
|
writeBuckets(buckets, outputDir);
|
|
} catch (err) {
|
|
process.stderr.write(`split-jscpd-report: ${err.message}\n`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
main();
|
|
}
|