Files
toolbox-portal/scripts/package-static.mjs

72 lines
2.3 KiB
JavaScript

#!/usr/bin/env node
import { access, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
import path from 'node:path';
import { createStaticArchive } from './archive.mjs';
import { sha256File } from './artifact.mjs';
import {
assertSafeRemovalTarget,
canonicalExistingPath,
canonicalPathsOverlap,
} from './path-safety.mjs';
import { publishStagedTargets } from './publication.mjs';
function argument(name, fallback) {
const index = process.argv.indexOf(name);
return index >= 0 ? process.argv[index + 1] : fallback;
}
const input = await canonicalExistingPath(
argument('--input', 'build/toolbox'),
'Static archive input'
);
const output = await assertSafeRemovalTarget(
argument('--output', 'artifacts/add-ideas-toolbox-static.zip')
);
const checksumOutput = await assertSafeRemovalTarget(`${output}.sha256`);
const force = process.argv.includes('--force');
if (path.extname(output).toLocaleLowerCase() !== '.zip')
throw new Error('Archive output must use a .zip extension.');
if (canonicalPathsOverlap(output, input))
throw new Error('Archive output and input directory must not overlap.');
const outputExists = await access(output).then(
() => true,
() => false
);
const checksumExists = await access(checksumOutput).then(
() => true,
() => false
);
if (outputExists && !force)
throw new Error(
`Archive already exists (use --force to replace it): ${output}`
);
if (checksumExists && !force)
throw new Error(
`Checksum already exists (use --force to replace it): ${checksumOutput}`
);
await mkdir(path.dirname(output), { recursive: true });
const staging = await mkdtemp(
path.join(path.dirname(output), '.toolbox-package-')
);
const stagedArchive = path.join(staging, path.basename(output));
const stagedChecksum = `${stagedArchive}.sha256`;
try {
await createStaticArchive(input, stagedArchive);
const checksum = await sha256File(stagedArchive);
await writeFile(stagedChecksum, `${checksum} ${path.basename(output)}\n`, {
flag: 'wx',
});
await publishStagedTargets(
[
{ staged: stagedArchive, target: output },
{ staged: stagedChecksum, target: checksumOutput },
],
{ force }
);
} finally {
await rm(staging, { recursive: true, force: true });
}
process.stdout.write(`Created ${output}\nChecksum: ${checksumOutput}\n`);