summaryrefslogtreecommitdiff
path: root/cgithub/scripts
diff options
context:
space:
mode:
authorJoe Mou <dev@mou.fo>2026-09-18 07:27:21 +0100
committerJoe Mou <dev@mou.fo>2026-09-18 07:27:21 +0100
commit9659525bf2387af6deab9d401784b94b1f44d395 (patch)
treec67dc1dd05bf2a8fa48dc123d6353d255a658ef1 /cgithub/scripts
parent9819d8e5504d6f03d27ec6b8786eec8fe5a752a5 (diff)
parent01494e6fa1345a509560e5e19a7f08cb2aac5cc8 (diff)
Merge commit 'FILTERED_HEAD'HEADmain
Diffstat (limited to 'cgithub/scripts')
-rw-r--r--cgithub/scripts/build.ts64
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`);