aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/plugins/updates.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/updates.ts')
-rw-r--r--src/plugins/updates.ts76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/plugins/updates.ts b/src/plugins/updates.ts
new file mode 100644
index 0000000..cd6dd54
--- /dev/null
+++ b/src/plugins/updates.ts
@@ -0,0 +1,76 @@
+import { execSync } from "node:child_process";
+import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
+
+/**
+ * ホームページの「更新情報」をビルド時に生成する。
+ *
+ * git の履歴から「新しく公開したページ」だけを拾い(--diff-filter=A)、
+ * そのページのフロントマターの title と URL を組みにして src/data/updates.json に書き出す。
+ * 加筆や内部の修正は拾わないので、一覧が作業ログで埋まらない。
+ *
+ * 生成結果はコミットしておく(git の履歴がない環境でもビルドできるように)。
+ */
+export default function updatesIntegration() {
+ return {
+ name: "build-updates",
+ hooks: {
+ "astro:config:setup": () => {
+ const items: { date: string; title: string; url: string; group: string }[] = [];
+ try {
+ const out = execSync(
+ 'git log --diff-filter=A --name-only --date=short --format="%x01%ad" -- src/content/docs',
+ { encoding: "utf-8", maxBuffer: 64 * 1024 * 1024 },
+ );
+ // 新しく追加されたファイル → そのコミットの日付(git log は新しい順なので最初の出現が追加時)
+ const added = new Map<string, string>();
+ let date = "";
+ for (const line of out.split("\n")) {
+ if (line.startsWith("\u0001")) {
+ date = line.slice(1).trim();
+ continue;
+ }
+ const file = line.trim();
+ if (!file.endsWith(".mdx") || file.endsWith("/index.mdx")) continue;
+ if (!added.has(file)) added.set(file, date);
+ }
+
+ const reiwa = (dir: string) => {
+ const n = Number(dir.replace(/^r(\d+)d$/, "$1"));
+ return n === 1 ? "令和元年" : `令和${n}年`;
+ };
+
+ for (const [file, d] of added) {
+ try {
+ const src = readFileSync(file, "utf-8");
+ const m = src.match(/^title:\s*"?(.+?)"?\s*$/m);
+ if (!m) continue;
+ const slug = file
+ .replace(/^src\/content\/docs\//, "")
+ .replace(/\.mdx$/, "");
+ const url = `/${slug}/`;
+ let group = "";
+ const mm = slug.match(/^ippan-situmon\/(r\d+d)\/(\d+)gatu\//);
+ if (mm) group = `${reiwa(mm[1])}${mm[2]}月定例会`;
+ items.push({ date: d, title: m[1], url, group });
+ } catch {
+ // 追加後に改名・削除されたファイルは飛ばす
+ }
+ }
+ items.sort((a, b) => b.date.localeCompare(a.date));
+ } catch (e) {
+ console.warn("[updates] git から取得できませんでした:", (e as Error).message);
+ }
+ try {
+ mkdirSync("src/data", { recursive: true });
+ writeFileSync(
+ "src/data/updates.json",
+ JSON.stringify(items.slice(0, 40), null, 2) + "\n",
+ );
+ console.log(`[updates] ${items.length}件のうち直近${Math.min(items.length, 40)}件を書き出しました`);
+ } catch (e) {
+ console.warn("[updates] 書き出しに失敗しました:", (e as Error).message);
+ }
+ },
+ },
+ };
+}