From f708088ef7183336e9a6f0f3cbd22207cfb91765 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 1 Feb 2025 16:25:45 +0100 Subject: [PATCH] Re-organise cli.ts into functions and sub-commands Add the necessary boilerplate for cli.ts to provide more than one command, with the resource gathering step split out from the build step in order for it to be re-usable. --- cli.ts | 77 +++++++++++++++++++++++++++++++++++++++++----------- package.json | 2 +- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/cli.ts b/cli.ts index 1f2dfe1..cd48c1a 100644 --- a/cli.ts +++ b/cli.ts @@ -19,22 +19,67 @@ function pageToHtml(page: Page) { ) } -const outDir = "build/web"; -if (!fs.existsSync(outDir)) { - fs.mkdirSync(outDir); -} - -for (const page of pages) { - const dirSep = page.ref.indexOf("/", 1); - if (dirSep !== -1) { - const dir = `${outDir}/${page.ref.slice(0, dirSep)}`; - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir); - } +function assembleResources() { + const webDir = "public"; + const resources = new Map(); + for (const entry of fs.readdirSync(webDir, { recursive: true, withFileTypes: true })) { + if (!entry.isFile()) + continue; + const parentPath = entry.parentPath.replace(/\\/g, "/"); + const ref = `${parentPath.slice(webDir.length)}/${entry.name}`; + resources.set(ref, `${parentPath}/${entry.name}`); } - console.log(`writing ${outDir}${page.ref}`); - fs.writeFileSync(`${outDir}${page.ref}`, pageToHtml(page)); + for (const page of pages) { + if (resources.has(page.ref)) { + const existing = resources.get(page.ref)!; + const other = typeof existing === "string" ? "a static resource" : `"${existing.title}"`; + throw new Error(`ref "${page.ref}" is taken up by both "${page.title}" and ${other}`) + } + resources.set(page.ref, page); + } + return resources; } -console.log(`writing ${outDir}/style.css`); -fs.writeFileSync(`${outDir}/style.css`, fs.readFileSync("public/style.css")); +function build() { + const outDir = "build/web"; + const dirsCreated = new Set() + for (const [ref, resource] of assembleResources()) { + const refDir = `${outDir}${posix.dirname(ref)}`; + if (!dirsCreated.has(refDir)) { + fs.mkdirSync(refDir, { recursive: true }); + } + console.log(`writing ${outDir}${ref}`); + let content; + if (typeof resource === "string") { + content = fs.readFileSync(resource); + } else { + content = pageToHtml(resource); + } + fs.writeFileSync(`${outDir}${ref}`, content); + } +} + +function printUsage() { + console.log("Usage: cli.js "); + console.log(" build - Copy resources and generated pages to build directory."); +} + +function main(runtime: string, script: string, args: string[]) { + if (!args.length) { + printUsage(); + process.exitCode = 1; + return; + } + + const [command, ...commandArgs] = args; + if (command === "build") { + build(); + } else { + console.log(`Error: Unkown sub-command ${command}`); + printUsage(); + process.exitCode = 1; + } +} + +const [runtime, script, ...args] = process.argv; +main(runtime, script, args) diff --git a/package.json b/package.json index 01d6d2b..fe91023 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "main": "build/node/index.js", "scripts": { "prepare": "tsc", - "build": "node --enable-source-maps build/node/cli.js", + "build": "node --enable-source-maps build/node/cli.js build", "test": "node --test --enable-source-maps --experimental-test-coverage" }, "dependencies": {