#!/usr/bin/env -S deno run -A /** Non-interactive entry: validate | generate | deploy */ import { parseArgs } from "@std/cli/parse-args"; import { join } from "@std/path"; import { DEFAULT_BS_MANAGER_CAMPAIGNS, DEFAULT_DIST_DIR, DEFAULT_INVENTORY_PATH, } from "./lib/paths.ts"; import { generateCampaignToDist } from "./lib/generate.ts"; import { defaultInventoryTemplate, readCampaignInventory, writeCampaignInventory, } from "./lib/inventory.ts"; import { deployCampaignFolder } from "./lib/deploy.ts"; import { formatIssues, validateGeneratedFolder, validateInventory, } from "./lib/validate.ts"; function usage(): string { return ` ost-campaign tools (Deno) Usage: deno task validate [--inventory ] [--dist ] deno task generate [--inventory ] [--dist-dir ] deno task deploy [--dist ] [--to ] [--dry-run] [--name ] Defaults: inventory: ${DEFAULT_INVENTORY_PATH} dist-root: ${DEFAULT_DIST_DIR} deploy to: ${DEFAULT_BS_MANAGER_CAMPAIGNS} Environment: BS_MANAGER_CUSTOM_CAMPAIGNS Overrides default BSManager CustomCampaigns path `.trim(); } async function cmdValidate(invPath: string, distDir?: string): Promise { const inv = await readCampaignInventory(invPath); const invIssues = validateInventory(inv); console.log(invIssues.length ? formatIssues(invIssues) : "(inventory OK)"); let code = invIssues.some((x) => x.level === "error") ? 1 : 0; if (distDir) { try { await Deno.stat(distDir); } catch { console.error(`Missing dist folder: ${distDir}`); return 1; } const disk = await validateGeneratedFolder(inv, distDir); if (disk.length) { console.log("--- generated folder ---"); console.log(formatIssues(disk)); } if (disk.some((x) => x.level === "error")) code = 1; } return code; } async function cmdGenerate(invPath: string, distRoot: string): Promise { const inv = await readCampaignInventory(invPath); const invIssues = validateInventory(inv); const errors = invIssues.filter((x) => x.level === "error"); if (errors.length) { console.error(formatIssues(errors)); console.error("(fix inventory errors before generating)"); return 1; } const { outDir, missionCount } = await generateCampaignToDist(inv, distRoot); console.log(`Wrote ${missionCount} missions to ${outDir}`); return 0; } async function cmdDeploy( distCampaignDir: string, destParent: string, dryRun: boolean, folderName?: string, ): Promise { const { destDir, files } = await deployCampaignFolder({ srcDir: distCampaignDir, destParentDir: destParent, folderName, dryRun, }); if (dryRun) { console.log(`Dry run: would copy ${files} files to ${destDir}`); } else { console.log(`Copied ${files} files -> ${destDir}`); } return 0; } async function seedInventoryIfMissing(path: string): Promise { try { await Deno.stat(path); } catch { const tmpl = defaultInventoryTemplate(); await writeCampaignInventory(path, tmpl); console.log(`Created starter inventory at ${path}`); } } const parsed = parseArgs(Deno.args, { alias: { i: "inventory", I: "inventory", h: "help", }, boolean: ["help", "dry-run"], string: ["inventory", "dist", "dist-dir", "to", "name"], }); if (parsed.help || parsed._.length === 0) { console.log(usage()); Deno.exit(parsed.help ? 0 : 1); } const cmd = String(parsed._[0]); (async () => { const invPath = parsed.inventory ?? DEFAULT_INVENTORY_PATH; if (cmd === "validate") { try { await Deno.stat(invPath); } catch { console.error(`Inventory not found: ${invPath}`); Deno.exit(1); } let distDir: string | undefined = parsed.dist; if (!distDir) { try { const inv = await readCampaignInventory(invPath); const candidate = join(DEFAULT_DIST_DIR, inv.outputFolderName); try { await Deno.stat(candidate); distDir = candidate; } catch { distDir = undefined; } } catch { distDir = undefined; } } Deno.exit(await cmdValidate(invPath, distDir)); } if (cmd === "generate") { await seedInventoryIfMissing(invPath); const distRoot = parsed["dist-dir"] ?? DEFAULT_DIST_DIR; Deno.exit(await cmdGenerate(invPath, distRoot)); } if (cmd === "deploy") { let distCampaignDir = parsed.dist; const folderName = parsed.name; await seedInventoryIfMissing(invPath); if (!distCampaignDir) { const inv = await readCampaignInventory(invPath); distCampaignDir = join(DEFAULT_DIST_DIR, inv.outputFolderName); } const dry = parsed["dry-run"] === true; const dest = parsed.to ?? DEFAULT_BS_MANAGER_CAMPAIGNS; Deno.exit(await cmdDeploy(distCampaignDir, dest, dry, folderName)); } console.error(`Unknown command: ${cmd}`); console.log(usage()); Deno.exit(1); })();