Files
gitea-themes/scripts/build.ts
T

103 lines
2.7 KiB
TypeScript

import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
import { watch } from "node:fs";
import { dirname, join } from "node:path";
import { transform } from "lightningcss";
import { githubDarkTheme, githubLightTheme } from "../themes";
import { createStylesheet } from "../styles/index";
const root = process.cwd();
const minify = process.argv.includes("--minify");
const watchMode = process.argv.includes("--watch");
const themes = [
{
filename: "theme-github-dev.css",
source: githubLightTheme,
},
{
filename: "theme-github-dev-dark.css",
source: githubDarkTheme,
},
];
async function writeIfChanged(output: string, content: Buffer | string) {
try {
const current = await readFile(output);
if (Buffer.compare(current, Buffer.from(content)) === 0) {
return;
}
} catch {
// Missing files are created below.
}
await mkdir(dirname(output), { recursive: true });
await writeFile(output, content);
}
async function syncDir(source: string, target: string) {
const entries = await readdir(source, { withFileTypes: true });
await Promise.all(
entries.map(async (entry) => {
const sourcePath = join(source, entry.name);
const targetPath = join(target, entry.name);
if (entry.isDirectory()) {
await syncDir(sourcePath, targetPath);
return;
}
if (entry.isFile()) {
await writeIfChanged(targetPath, await readFile(sourcePath));
}
}),
);
}
async function build() {
const cssOutputs = await Promise.all(
themes.flatMap((theme) => {
const result = transform({
filename: theme.filename,
code: Buffer.from(createStylesheet(theme.source)),
minify,
targets: {
chrome: 108 << 16,
firefox: 108 << 16,
safari: 16 << 16,
},
});
return [
writeIfChanged(join(root, "dist", theme.filename), result.code),
writeIfChanged(join(root, ".gitea", "custom", "public", "assets", "css", theme.filename), result.code),
];
}),
);
await Promise.all([
syncDir(join(root, "templates"), join(root, ".gitea", "custom", "templates")),
syncDir(join(root, "options"), join(root, ".gitea", "custom", "options")),
]);
console.log(`built ${cssOutputs.length} css outputs`);
}
await build();
if (watchMode) {
console.log("watching styles, themes, and src");
const watchedDirs = [join(root, "styles"), join(root, "themes"), join(root, "src")];
const watchers = watchedDirs.map((dir) =>
watch(dir, { recursive: true }, async (_eventType, filename) => {
if (filename?.endsWith(".ts")) {
await build();
}
}),
);
process.on("SIGINT", () => {
watchers.forEach((watcher) => watcher.close());
process.exit(0);
});
}