-
Notifications
You must be signed in to change notification settings - Fork 0
/
commits.ts
91 lines (77 loc) · 3.61 KB
/
commits.ts
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
80
81
82
83
84
85
86
87
88
89
90
91
import fs from "fs"
import path from "path"
import { NextApiRequest, NextApiResponse } from "next"
import { execSync } from "child_process"
const handler = (_req: NextApiRequest, res: NextApiResponse) => {
if (process.env.NODE_ENV !== "development") {
res.status(403).json({ error: "This API is only available in development mode." })
return
}
const basePath = path.join(process.cwd(), "versions")
const commitHashes = fs.readdirSync(basePath)
const formatDate = (date: Date): string => {
const now = new Date()
const diff = now.getTime() - date.getTime()
const seconds = Math.floor(diff / 1000)
const minutes = Math.floor(seconds / 60)
const hours = Math.floor(minutes / 60)
const days = Math.floor(hours / 24)
const months = Math.floor(days / 30)
const years = Math.floor(months / 12)
let ago = ""
if (years > 0) {
ago = `(${years} year${years > 1 ? "s" : ""}${months % 12 > 0 ? `, ${months % 12} month${months % 12 > 1 ? "s" : ""}` : ""} ago)`
} else if (months > 0) {
ago = `(${months} month${months > 1 ? "s" : ""}${days % 30 > 0 ? `, ${days % 30} day${days % 30 > 1 ? "s" : ""}` : ""} ago)`
} else if (days > 0) {
ago = `(${days} day${days > 1 ? "s" : ""}${hours % 24 > 0 ? `, ${hours % 24} hour${hours % 24 > 1 ? "s" : ""}` : ""} ago)`
} else if (hours > 0) {
ago = `(${hours} hour${hours > 1 ? "s" : ""} ago)`
} else if (minutes > 0) {
ago = `(${minutes} minute${minutes > 1 ? "s" : ""} ago)`
} else {
ago = `(${seconds} second${seconds > 1 ? "s" : ""} ago)`
}
return `${date.toISOString().slice(0, 19).replace("T", " ")} ${ago}`
}
const commits = commitHashes
.map((commit) => {
const commitPath = path.join(basePath, commit)
const commitStat = fs.statSync(commitPath)
if (commitStat.isDirectory() && fs.readdirSync(commitPath).length > 0) {
try {
const logOutput = execSync(`git log -1 ${commit}`).toString().trim()
const message = execSync(`git log -1 --pretty=format:%s ${commit}`).toString().trim()
const rawDate = execSync(`git log -1 --pretty=format:%cI ${commit}`).toString().trim()
const authorRegex = /^Author:\s+(.+?)\s*<.+?>$/m
const authorMatch = logOutput.match(authorRegex)
const author = authorMatch ? authorMatch[1] : ""
const diffOutput = execSync(`git diff ${commit}~1 ${commit} --shortstat`).toString().trim()
return {
hash: commit,
message,
author,
rawDate,
formattedDate: formatDate(new Date(rawDate)),
diff: diffOutput,
}
} catch (error) {
console.error(`Error fetching commit data: ${error.message}`)
return null
}
}
return null
})
.filter(Boolean)
.sort((a, b) => new Date(b.rawDate).getTime() - new Date(a.rawDate).getTime()) // Sort commits by date
// Replace the rawDate with formattedDate, include author and diff for response
const responseCommits = commits.map(({ hash, message, author, formattedDate, diff }) => ({
hash,
message,
author,
date: formattedDate,
diff,
}))
res.status(200).json(responseCommits)
}
export default handler