Skip to content

Commit e9798cd

Browse files
committed
refactor: error handling, add commit link
1 parent 78b2191 commit e9798cd

File tree

3 files changed

+96
-67
lines changed

3 files changed

+96
-67
lines changed
Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
11
---
2-
import { type GitHubAccount, getGitHubAccountFromFile } from "/src/utils/git-utils.ts";
2+
import { REPO, getCommitInfo } from "../../utils/git";
33
44
const { lang, lastUpdated } = Astro.locals.starlightRoute;
55
const filePath = Astro.locals.starlightRoute.entry.filePath;
66
7-
const acc: GitHubAccount = await getGitHubAccountFromFile(filePath);
7+
const info = await getCommitInfo(filePath);
88
---
99

1010
{
1111
lastUpdated && (
12-
<p>
13-
{"Last updated: "}
14-
<time datetime={lastUpdated.toISOString()}>
15-
{lastUpdated.toLocaleDateString(lang, {
16-
dateStyle: "medium",
17-
timeZone: "UTC",
18-
})}
19-
</time>
20-
{" by "}
21-
<a href={acc.accountLink}>{acc.displayName}</a>
22-
</p>
12+
<div class="last-updated">
13+
<p>
14+
Last updated:
15+
<time datetime={lastUpdated.toISOString()}>
16+
{lastUpdated.toLocaleDateString(lang, {
17+
dateStyle: "medium",
18+
timeZone: "UTC",
19+
})}
20+
</time>
21+
</p>
22+
{info && (
23+
<p class="commit">
24+
by <a href={info.committer.href}>{info.committer.name}</a> in{" "}
25+
<a href={`https://github.com/${REPO}/commit/${info.hash}`}>{info.hash.substring(0, 7)}</a>
26+
</p>
27+
)}
28+
</div>
2329
)
2430
}
31+
32+
<style>
33+
.last-updated {
34+
display: flex;
35+
flex-direction: column;
36+
line-height: 1.5;
37+
}
38+
39+
.commit {
40+
font-size: var(--sl-text-2xs);
41+
}
42+
</style>

src/utils/git-utils.ts

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/utils/git.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { execSync } from "child_process";
2+
3+
export interface CommitterInfo {
4+
name: string;
5+
href: string;
6+
}
7+
8+
export interface CommitInfo {
9+
hash: string;
10+
committer: CommitterInfo;
11+
}
12+
13+
const token: string | null = import.meta.env.GITHUB_TOKEN;
14+
15+
const options: RequestInit =
16+
token != null
17+
? {
18+
headers: {
19+
Accept: "application/vnd.github+json",
20+
"User-Agent": "papermc-docs/author",
21+
Authorization: `Bearer ${token}`,
22+
},
23+
}
24+
: {
25+
headers: {
26+
Accept: "application/vnd.github+json",
27+
"User-Agent": "papermc-docs/author",
28+
},
29+
};
30+
31+
export const REPO = "PaperMC/docs";
32+
const cache = new Map<string, CommitterInfo>();
33+
34+
export const getCommitInfo = async (filePath: string): Promise<CommitInfo | null> => {
35+
let email: string, hash: string;
36+
try {
37+
email = execSync(`git log -1 --pretty="format:%ae" -- "${filePath}"`).toString();
38+
hash = execSync(`git log -1 --pretty="format:%H" -- "${filePath}"`).toString();
39+
} catch (e) {
40+
return null;
41+
}
42+
43+
const cached = cache.get(email);
44+
if (cached) {
45+
return { hash, committer: cached };
46+
}
47+
48+
let name: string;
49+
try {
50+
name = execSync(`git log -1 --pretty="format:%an" -- "${filePath}"`).toString();
51+
} catch (e) {
52+
return null;
53+
}
54+
55+
const info: CommitterInfo = { name, href: `mailto:${email}` };
56+
57+
const res = await fetch(`https://api.github.com/repos/${REPO}/commits/${hash}`, options);
58+
if (res.ok) {
59+
const commit = await res.json();
60+
info.href = commit.author.html_url;
61+
}
62+
63+
cache.set(email, info);
64+
return { hash, committer: info };
65+
};

0 commit comments

Comments
 (0)