113 lines
2.6 KiB
TypeScript
113 lines
2.6 KiB
TypeScript
#!/usr/bin/env bun
|
|
import { existsSync } from "node:fs";
|
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import { join, resolve } from "node:path";
|
|
|
|
const moduleNames = [
|
|
"amezing",
|
|
"analysis",
|
|
"astro",
|
|
"database",
|
|
"latex",
|
|
"mdx",
|
|
"optimize",
|
|
"prettier-plugin",
|
|
"shadcn",
|
|
"tailwind",
|
|
] as const;
|
|
const root = resolve(import.meta.dir, "..");
|
|
const api = (process.env.MUDDLE_FORGEJO_URL ?? "https://git.crit.rip").replace(
|
|
/\/$/,
|
|
"",
|
|
);
|
|
const owner = process.env.MUDDLE_FORGEJO_OWNER ?? "mdl";
|
|
const dryRun = process.argv.includes("--dry-run");
|
|
const token = process.env.MUDDLE_FORGEJO_TOKEN;
|
|
|
|
if (!dryRun && !token) {
|
|
throw new Error(
|
|
"Set MUDDLE_FORGEJO_TOKEN or use --dry-run.",
|
|
);
|
|
}
|
|
|
|
async function forgejo(
|
|
path: string,
|
|
init: RequestInit = {},
|
|
): Promise<Response> {
|
|
if (dryRun) return new Response(null, { status: 204 });
|
|
return fetch(`${api}/api/v1${path}`, {
|
|
...init,
|
|
headers: {
|
|
Authorization: `token ${token}`,
|
|
Accept: "application/json",
|
|
"Content-Type": "application/json",
|
|
...init.headers,
|
|
},
|
|
});
|
|
}
|
|
|
|
async function ensureWorkspaceModule(name: string): Promise<void> {
|
|
const dir = join(root, "modules", name);
|
|
await mkdir(dir, { recursive: true });
|
|
const manifest = join(dir, "package.json");
|
|
if (!existsSync(manifest)) {
|
|
await writeFile(
|
|
manifest,
|
|
`${
|
|
JSON.stringify(
|
|
{
|
|
name: `@muddle/${name}`,
|
|
version: "0.1.0",
|
|
type: "module",
|
|
exports: "./index.ts",
|
|
peerDependencies: { muddle: "*" },
|
|
},
|
|
null,
|
|
2,
|
|
)
|
|
}\n`,
|
|
);
|
|
await writeFile(join(dir, "index.ts"), "export {};\n");
|
|
}
|
|
const parsed = JSON.parse(await readFile(manifest, "utf8")) as {
|
|
name?: string;
|
|
};
|
|
if (parsed.name !== `@muddle/${name}`) {
|
|
throw new Error(`${manifest} must declare @muddle/${name}`);
|
|
}
|
|
}
|
|
|
|
async function ensureRemoteRepository(name: string): Promise<void> {
|
|
const response = await forgejo(`/repos/${owner}/${name}`);
|
|
if (response.status === 200 || response.status === 204) return;
|
|
if (response.status !== 404) {
|
|
throw new Error(
|
|
`Unable to inspect ${owner}/${name}, Forgejo returned ${response.status}`,
|
|
);
|
|
}
|
|
const created = await forgejo(`/orgs/${owner}/repos`, {
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
name,
|
|
private: false,
|
|
description: `@muddle/${name} integration module`,
|
|
}),
|
|
});
|
|
if (!created.ok) {
|
|
throw new Error(
|
|
`Unable to create ${owner}/${name}, Forgejo returned ${created.status}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
for (const name of moduleNames) {
|
|
await ensureWorkspaceModule(name);
|
|
await ensureRemoteRepository(name);
|
|
console.log(
|
|
`${
|
|
dryRun
|
|
? "would provision"
|
|
: "provisioned"
|
|
} @muddle/${name} at ${api}/${owner}/${name}`,
|
|
);
|
|
}
|