Files
houseplan-card/scripts/mutation-bundle-cache.mjs
T

59 lines
2.2 KiB
JavaScript

// One clean frontend bundle can serve every browser mutant whose patch does
// not touch a bundle input. Keep this policy outside the execution lifecycle:
// the runner applies it, while tests can judge it without making worktrees.
import { cpSync, existsSync, mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { fingerprintCorpus } from './source-fingerprint.mjs';
const repoRoot = fileURLToPath(new URL('..', import.meta.url));
const BUNDLE_CORPUS = new Set(fingerprintCorpus(repoRoot));
const BUNDLE_TREES = ['dist', 'demo/srv/assets'];
export function guardNeedsBundle(guard) {
return guard.includes('demo/') || guard.includes('bundle:sync');
}
export function mutantPatchesNeedBundle(patches, corpus = BUNDLE_CORPUS) {
const bundled = corpus instanceof Set ? corpus : new Set(corpus);
return patches.some((patch) => bundled.has(patch.file.replaceAll('\\', '/')));
}
export function mutantBundleStrategy(mutant, { seedAvailable = false, corpus } = {}) {
if (!guardNeedsBundle(mutant.guard)) return 'none';
if (seedAvailable && !mutantPatchesNeedBundle(mutant.patches, corpus)) return 'seed';
return 'build';
}
export const planNeedsBundleSeed = (mutants) => mutants.some((mutant) => (
guardNeedsBundle(mutant.guard) && !mutantPatchesNeedBundle(mutant.patches)
));
export const makeBundleSeed = () => mkdtempSync(join(tmpdir(), 'hp-mutant-bundle-'));
export function dropBundleSeed(dir) {
if (dir) rmSync(dir, { recursive: true, force: true });
}
export function captureBundleSeed(root, seed) {
for (const name of BUNDLE_TREES) {
const from = join(root, name);
if (!existsSync(from)) throw new Error(`bundle seed source is missing: ${name}`);
const to = join(seed, name);
rmSync(to, { recursive: true, force: true });
cpSync(from, to, { recursive: true });
}
}
export function restoreBundleSeed(seed, root) {
for (const name of BUNDLE_TREES) {
const from = join(seed, name);
if (!existsSync(from)) throw new Error(`shared bundle seed is missing: ${name}`);
const to = join(root, name);
rmSync(to, { recursive: true, force: true });
cpSync(from, to, { recursive: true });
}
}