103 lines
2.7 KiB
TypeScript
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);
|
|
});
|
|
}
|