1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
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");
// 下書き(draft: true)は本番に出ないので除外する
const fm = src.match(/^---\r?\n([\s\S]*?)\r?\n---/);
if (fm && /^draft:\s*true\s*$/m.test(fm[1])) continue;
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);
}
},
},
};
}
|