diff options
Diffstat (limited to 'cgithub/scripts')
| -rw-r--r-- | cgithub/scripts/build.ts | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/cgithub/scripts/build.ts b/cgithub/scripts/build.ts new file mode 100644 index 0000000..4908532 --- /dev/null +++ b/cgithub/scripts/build.ts @@ -0,0 +1,64 @@ +// Generates the sources that can't exist at runtime on Workers: +// +// src/views.generated.ts - views/*.eta precompiled into plain functions. +// Workers disallow runtime code generation (`new Function`), so Eta cannot +// compile templates there at request time. +// src/build.generated.ts - the commit this build was made from, for the +// page footer. Workers can't shell out to git at request time either. +import { execFileSync } from "node:child_process"; +import { Eta } from "eta"; +import fs from "node:fs"; +import path from "node:path"; + +const root = path.join(import.meta.dirname, ".."); +const viewsDir = path.join(root, "views"); +const eta = new Eta({ views: viewsDir }); + +// Names are the templates' paths under views/, e.g. "layouts/base.eta", which +// is how the templates address each other (see src/worker.ts). +function templateNames(dir: string, prefix = ""): string[] { + const names: string[] = []; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const name = prefix + entry.name; + if (entry.isDirectory()) { + names.push(...templateNames(path.join(dir, entry.name), `${name}/`)); + } else if (entry.name.endsWith(".eta")) { + names.push(name); + } + } + return names.sort(); +} + +const names = templateNames(viewsDir); + +let out = `// @ts-nocheck +// Generated by scripts/build.ts -- do not edit. +export const views = { +`; +for (const name of names) { + const source = fs.readFileSync(path.join(viewsDir, name), "utf8"); + const body = eta.compileToString(source); + out += ` ${JSON.stringify(name)}: function (it, options) {\n${body}\n },\n`; +} +out += "};\n"; + +fs.writeFileSync(path.join(root, "src", "views.generated.ts"), out); +console.log(`Compiled ${names.length} templates to src/views.generated.ts`); + +// Untagged repositories describe as a bare short hash; --dirty marks a build +// made from an unclean working copy. +let buildCommit = "unknown"; +try { + buildCommit = execFileSync("git", ["describe", "--tags", "--always", "--dirty"], { + cwd: root, + encoding: "utf8", + }).trim(); +} catch { + // Building from a source copy without git history. +} + +fs.writeFileSync( + path.join(root, "src", "build.generated.ts"), + `// Generated by scripts/build.ts -- do not edit.\nexport const buildCommit = ${JSON.stringify(buildCommit)};\n`, +); +console.log(`Wrote commit ${buildCommit} to src/build.generated.ts`); |
