59 lines
2.4 KiB
JavaScript
59 lines
2.4 KiB
JavaScript
import { link, readFile, rm } from "node:fs/promises";
|
|
import { join, resolve } from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
import { atomicWrite, EDUCATIONAL_WARNING, networkSpec, readManifest } from "./finalize-manifest.mjs";
|
|
|
|
export async function selectManifest({ root = process.cwd(), network }) {
|
|
const spec = networkSpec(network);
|
|
const source = join(root, "deployments", spec.canonical);
|
|
await readManifest(source);
|
|
const contents = await readFile(source);
|
|
const active = join(root, "deployments", "active.json");
|
|
await atomicWrite(active, contents);
|
|
return { source, active };
|
|
}
|
|
|
|
export async function archiveManifest({ root = process.cwd(), network, now = new Date(), io = {} }) {
|
|
if (network !== "baseSepolia") throw new Error("only baseSepolia may be archived");
|
|
const spec = networkSpec(network);
|
|
const source = join(root, "deployments", spec.canonical);
|
|
await readManifest(source);
|
|
if (!(now instanceof Date) || Number.isNaN(now.valueOf())) throw new Error("archive timestamp is invalid");
|
|
const timestamp = now.toISOString().replace(/[-:.]/g, "");
|
|
if (!/^\d{8}T\d{9}Z$/.test(timestamp)) throw new Error("archive timestamp is invalid");
|
|
const target = join(root, "deployments", `base-sepolia.${timestamp}.json`);
|
|
const operations = { link, rm, ...io };
|
|
try {
|
|
await operations.link(source, target);
|
|
} catch (error) {
|
|
if (error.code === "EEXIST") throw new Error("refusing to overwrite an existing Base Sepolia archive");
|
|
throw error;
|
|
}
|
|
try {
|
|
await operations.rm(source);
|
|
} catch (error) {
|
|
throw new Error(
|
|
`archive created at ${target}, but source ${source} could not be removed; both paths were preserved: ${error.message}`,
|
|
{ cause: error },
|
|
);
|
|
}
|
|
return { source, path: target };
|
|
}
|
|
|
|
export async function runSelectCli(argv, { root = process.cwd(), log = console.log } = {}) {
|
|
log(EDUCATIONAL_WARNING);
|
|
if (argv.length === 2 && argv[0] === "archive" && argv[1] === "baseSepolia") {
|
|
return archiveManifest({ root, network: argv[1] });
|
|
}
|
|
if (argv.length !== 1) throw new Error("usage: select-manifest.mjs <anvil|baseSepolia> | archive baseSepolia");
|
|
return selectManifest({ root, network: argv[0] });
|
|
}
|
|
|
|
if (process.argv[1] && pathToFileURL(resolve(process.argv[1])).href === import.meta.url) {
|
|
runSelectCli(process.argv.slice(2)).catch((error) => {
|
|
console.error(error.message);
|
|
process.exitCode = 1;
|
|
});
|
|
}
|