Sun Nov 16 2025
Tucker McKnight <tucker@pangolin.lan>
More implementation of the new type The new commit field and branch heads work now, and other functions/filters/template pages work as expected with those new fields. Switch to the new Repository type is pretty much done now. Also did some miscellaneous things, like adding basic string types to some function arguments. Also started changing all uses of "patch" to "commit," which is a holdover from when this project started with darcs.
fb82fedb228595143547ae3003ba3426a5e39bc9
5
import paginatedPatches from './src/paginatedPatches.ts'
5
import paginatedPatches, {type PatchPage} from './src/paginatedPatches.ts'
49
async ({ directories, results, runMode, outputMode }) => {
49
async ({ directories }) => {
74
const mkdirresult = await exec(`mkdir ${tempDir}`)
74
await exec(`mkdir ${tempDir}`)
92
93
94
95
eleventyConfig.addFilter("getDirectoryContents", (repo, branch, dirPath) => {
return reposData.find(current => current.name === repo).branches[branch].fileList.filter(file => file.startsWith(dirPath) && file !== dirPath)
eleventyConfig.addFilter("getRelativePath", (currentDir, fullFilePath) => {
eleventyConfig.addFilter("lineNumbers", (code) => {
92
93
94
95
eleventyConfig.addFilter("getDirectoryContents", (repo: string, branch: string, dirPath: string) => {
return reposData.find(current => current.name === repo).branches.find(current => current.name === branch).fileList.filter(file => file.startsWith(dirPath) && file !== dirPath)
eleventyConfig.addFilter("getRelativePath", (currentDir: string, fullFilePath: string) => {
eleventyConfig.addFilter("lineNumbers", (code: string) => {
120
eleventyConfig.addAsyncFilter("renderContentIfAvailable", async (contentString, contentType) => {
120
eleventyConfig.addAsyncFilter("renderContentIfAvailable", async (contentString: string, contentType: string) => {
130
131
132
133
eleventyConfig.addFilter("languageExtension", (filename, repoName) => {
let extension = filename.split(".")
extension = extension[extension.length - 1]
eleventyConfig.addFilter("topLevelFilesOnly", (files, currentLevel) => {
130
131
132
133
eleventyConfig.addFilter("languageExtension", (filename: string, repoName: string) => {
let filenameParts = filename.split(".")
let extension = filenameParts[filenameParts.length - 1]
eleventyConfig.addFilter("topLevelFilesOnly", (files: Array<string>, currentLevel: string) => {
175
176
177
eleventyConfig.addAsyncFilter("getFileLastTouchInfo", async (repo, branch, filename) => {
const location = getLocation(reposConfiguration, branch, repo)
return repoOperations[config._type].getFileLastTouchInfo(repo, branch, filename, location)
175
176
177
eleventyConfig.addAsyncFilter("getFileLastTouchInfo", async (repo: string, branch: string, filename: string) => {
const location = getLocation(reposConfiguration, repo)
return repoOperations[config._type].getFileLastTouchInfo(branch, filename, location)
196
197
198
199
200
201
const location = getLocation(reposConfiguration, branch, repo)
eleventyConfig.addFilter("pagesJustForBranch", (pages, repoName, branchName) => {
eleventyConfig.addFilter("date", (dateString) => {
eleventyConfig.addFilter("toDateObj", (dateString) => {
eleventyConfig.addAsyncFilter("getReadMe", async (repoName, branchName) => {
const location = getLocation(reposConfiguration, branchName, repoName)
196
197
198
199
200
201
const location = getLocation(reposConfiguration, repo)
eleventyConfig.addFilter("pagesJustForBranch", (pages: Array<PatchPage>, repoName: string, branchName: string) => {
eleventyConfig.addFilter("date", (dateString: string) => {
eleventyConfig.addFilter("toDateObj", (dateString: string) => {
eleventyConfig.addAsyncFilter("getReadMe", async (repoName: string, branchName: string) => {
const location = getLocation(reposConfiguration, repoName)
260
}
260
261
262
263
264
265
266
267
268
269
path: "list"
},
currentRepo: (data) => reposData.find(repo => {
return repo.name === data.branchInfo.repoName
}),
currentBranch: (data) => reposData.find(repo => {
return repo.name === data.branchInfo.repoName
}).branches.find(branch => {
return branch.name === data.branchInfo.branchName
}),
288
}
288
289
290
291
292
293
294
295
296
297
path: "files",
},
currentRepo: (data) => reposData.find(repo => {
return repo.name === data.fileInfo.repoName
}),
currentBranch: (data) => reposData.find(repo => {
return repo.name === data.fileInfo.repoName
}).branches.find(branch => {
return branch.name === data.fileInfo.branchName
}),
335
335
path: "files",
369
369
path: "",
405
}
405
406
407
408
409
410
411
412
413
414
path: "patches/page1",
},
currentRepo: (data) => reposData.find(repo => {
return repo.name === data.patchPage.repoName
}),
currentBranch: (data) => reposData.find(repo => {
return repo.name === data.patchPage.repoName
}).branches.find(branch => {
return branch.name === data.patchPage.branchName
}),
427
428
return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/patches/${data.patchInfo.patch.hash}/`
}
427
428
429
430
431
432
433
434
435
436
437
return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/patches/${data.patchInfo.commit.hash}/`
path: "patches/page1",
},
currentRepo: (data) => reposData.find(repo => {
return repo.name === data.patchInfo.repoName
}),
currentBranch: (data) => reposData.find(repo => {
return repo.name === data.patchInfo.repoName
}).branches.find(branch => {
return branch.name === data.patchInfo.branchName
}),
13
{% set url = repos[nav.repoName].cloneUrl %}
13
{% set url = currentRepo.cloneUrl %}
83
84
{% for branch in repos[nav.repoName].branches %}
<option value="{{branch.repoName | slugify}},{{branch.branchName | slugify}},{{nav.path}}" {% if branch.branchName == nav.branchName %}selected{% endif %}>{{branch.branchName}}</option>
83
84
{% for branch in currentRepo.branches %}
<option value="{{currentRepo.name | slugify}},{{branch.name | slugify}},{{nav.path}}" {% if branch.name == nav.branchName %}selected{% endif %}>{{branch.name}}</option>
1
let cachedBranches = null
1
2
3
4
let cachedBranches: Array<{
branchName: string,
repoName: string,
}> | null = null
18
parent: string,
18
parent: string | null,
1
2
3
let cachedFlatPatches = null
export default async (repos: Array<Repository>) => {
return [] // todo implement this with new commits format
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
type FlatPatchRecord = {
commit: ReturnType<Repository['commits']['get']>,
repoName: string,
branchName: string,
}
let cachedFlatPatches: Array<FlatPatchRecord> | null = null
export default async (repos: Array<Repository>)
: Promise<Array<FlatPatchRecord>> => {
const flatPatches: Array<FlatPatchRecord> = []
let currentCommit: ReturnType<Repository['commits']['get']> | undefined = repo.commits.get(branch.head)
while (currentCommit !== undefined) {
flatPatches.push({
commit: currentCommit,
repoName: repo.name,
branchName: branch.name
})
currentCommit = repo.commits.get(currentCommit.parent)
}
return flatPatches
1
2
3
4
5
6
7
8
9
10
11
12
13
type NavValues = {
repoName: string | ((data: any) => string),
branchName: string | ((data: any) => string),
path: string | ((data: any) => string),
title: string | ((data: any) => string),
}
type Hunk = {
file: string,
lineNumber: number,
previousText: string,
afterText: string,
}
1
import { type ReposConfiguration } from './configTypes.ts'
82
83
const getLocation = (reposConfig: any, branchName: string, repoName: string): string => {
NavValues,
82
const getLocation = (reposConfig: ReposConfiguration, repoName: string): string => {
1
2
let paginatedPatches = null
export default async (repos) => {
1
2
3
4
5
6
7
8
9
import { type Repository } from './dataTypes.ts'
export type PatchPage = {
repoName: string,
branchName: string,
commits: Array<ReturnType<Repository['commits']['get']>>,
pageNumber: number,
}
let paginatedPatches: Array<PatchPage> | null = null
export default async (repos: Array<Repository>) => {
15
&& page.patches.length <= patchesPerPage
15
&& page.commits.length <= patchesPerPage
24
25
patches: [patch.patch],
paginatedPatches[index].patches.push(patch.patch)
24
25
commits: [patch.commit],
paginatedPatches[index].commits.push(patch.commit)
3
3
4
5
6
7
8
import util from 'util'
import childProcess from 'child_process'
import cloneUrl from './vcses/git/helpers.ts'
import { getFileList } from './vcses/git/operations.ts'
const exec = util.promisify(childProcess.exec)
30
31
32
33
34
35
36
37
38
39
const repoLocation = getLocation(reposConfig, branchName, repoName)
branches: branchNames.map((branchName) => {
return {
name: branchName,
head: "", // todo
fileList: [], //todo
}
}),
cloneUrl: "",
tags: [],
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
const repoLocation = getLocation(reposConfig, repoName)
const branches = await Promise.all(branchNames.map(async (branchName) => {
const repoLocation = getLocation(reposConfig, repoName)
const branchHeadRes = await exec(`(cd ${repoLocation} && git show-ref --branch ${branchName})`)
const branchHead = branchHeadRes.stdout.split(" ")[0]
return {
name: branchName,
head: branchHead,
fileList: await getFileList(branchName, repoLocation)
}
}))
branches,
cloneUrl: cloneUrl.cloneUrl(reposConfig.baseUrl, repoName),
tags: [], // todo
4
export const getFileList = async (repoName: string, branchName: string, repoLocation: string) => {
4
export const getFileList = async (branchName: string, repoLocation: string) => {
41
41
let previousHash: null | string = null
54
break
54
55
56
57
58
59
60
// set the parent hash of the previous commit, unless we're on the first commit
if (previousHash !== null) {
commits.get(previousHash)['parent'] = hash
}
previousHash = hash
return
83
84
85
diffs,
parent: "todo",
export const getFileLastTouchInfo = async (repo: string, branch: string, filename: string, repoLocation: string) => {
83
84
85
diffs,
parent: null,
export const getFileLastTouchInfo = async (branch: string, filename: string, repoLocation: string) => {
6
getFileLastTouchInfo: (repoName: string, branchName: string, filename: string, repoLocation: string) => Promise<Array<{sha: string, author: string}>>,
6
getFileLastTouchInfo: (branchName: string, filename: string, repoLocation: string) => Promise<Array<{sha: string, author: string}>>,
1
2
{% set description = reposConfig.repos[branch.repoName].branches[branch.branchName].description %}
<li><a href="{{reposPath}}/{{branch.repoName | slugify}}/branches/{{branch.branchName | slugify}}">{{branch.branchName}}</a>{% if branch.branchName == branchInfo.branchName %} (current){% endif %}{% if description %} - {{ description }}{% endif %}</li>
1
<li><a href="{{reposPath}}/{{branch.repoName | slugify}}/branches/{{branch.branchName | slugify}}">{{branch.branchName}}</a>{% if branch.branchName == branchInfo.branchName %} (current){% endif %}</li>
1
2
3
4
5
<h1>{{patchInfo.patch.name}}</h2>
<p>{{patchInfo.patch.date | date }}</p>
<p>{{patchInfo.patch.author }}</p>
<pre>{{patchInfo.patch.description}}</pre>
<p class="font-monospace fw-bold text-secondary">{{patchInfo.patch.hash}}</p>
1
2
3
4
5
<h1>commit first line goes here</h2>
<p>{{patchInfo.commit.date | date }}</p>
<p>{{patchInfo.commit.author }}</p>
<pre>{{patchInfo.commit.message}}</pre>
<p class="font-monospace fw-bold text-secondary">{{patchInfo.commit.hash}}</p>
24
{% set patchHunks = patchInfo.patch.diffs %}
24
{% set patchHunks = patchInfo.commit.diffs %}
9
10
11
12
13
{% for patch in patchPage.patches %}
<span class="patch-name"><a href="{{reposPath}}/{{patchPage.repoName | slugify}}/branches/{{patchPage.branchName | slugify}}/patches/{{patch.hash}}">{{patch.name}}</a></span>
<span>{{patch.date | date}}</span>
<span>{{patch.author}}</span>
<pre class="patch-hash">{{patch.hash}}</pre>
9
10
11
12
13
{% for commit in patchPage.commits %}
<span class="patch-name"><a href="{{reposPath}}/{{patchPage.repoName | slugify}}/branches/{{patchPage.branchName | slugify}}/patches/{{commit.hash}}">{{commit.message}}</a></span>
<span>{{commit.date | date}}</span>
<span>{{commit.author}}</span>
<pre class="patch-hash">{{commit.hash}}</pre>