Branch

commit first line goes here

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

Side-by-side
Stacked
main.ts:5
Before
5
import paginatedPatches from './src/paginatedPatches.ts'
After
5
import paginatedPatches, {type PatchPage} from './src/paginatedPatches.ts'
main.ts:49
Before
49
    async ({ directories, results, runMode, outputMode }) => {
After
49
    async ({ directories }) => {
main.ts:74
Before
74
          const mkdirresult = await exec(`mkdir ${tempDir}`)
After
74
          await exec(`mkdir ${tempDir}`)
main.ts:92
Before
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) => {
After
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) => {
main.ts:120
Before
120
  eleventyConfig.addAsyncFilter("renderContentIfAvailable", async (contentString, contentType) => {
After
120
  eleventyConfig.addAsyncFilter("renderContentIfAvailable", async (contentString: string, contentType: string) => {
main.ts:130
Before
130 131 132 133
  eleventyConfig.addFilter("languageExtension", (filename, repoName) => {
    let extension = filename.split(".")
    extension = extension[extension.length - 1]
  eleventyConfig.addFilter("topLevelFilesOnly", (files, currentLevel) => {
After
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) => {
main.ts:175
Before
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)
After
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)
main.ts:196
Before
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)
After
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)
main.ts:260
Before
260
        }
After
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
        }),
main.ts:288
Before
288
        }
After
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
        }),
main.ts:335
Before
335
After
335
          path: "files",
main.ts:369
Before
369
After
369
          path: "",
main.ts:405
Before
405
        }
After
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
        }),
main.ts:427
Before
427 428
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/patches/${data.patchInfo.patch.hash}/`
        }
After
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
        }),
partial_templates/main_top.njk:13
Before
13
    {% set url = repos[nav.repoName].cloneUrl %}
After
13
    {% set url = currentRepo.cloneUrl %}
partial_templates/main_top.njk:83
Before
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>
After
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>
src/branches.ts:1
Before
1
let cachedBranches = null
After
1 2 3 4
let cachedBranches: Array<{
  branchName: string,
  repoName: string,
}> | null = null
src/dataTypes.ts:18
Before
18
    parent: string,
After
18
    parent: string | null,
src/flatPatches.ts:1
Before
1 2 3
let cachedFlatPatches = null
export default async (repos: Array<Repository>) => {
      return [] // todo implement this with new commits format
After
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
src/helpers.ts:1
Before
1 2 3 4 5 6 7 8 9 10 11 12 13

type NavValues = {
  repoName: string | ((data: any) =&gt; string),
  branchName: string | ((data: any) =&gt; string),
  path: string | ((data: any) => string),
  title: string | ((data: any) => string),
}
type Hunk = {
  file: string,
  lineNumber: number,
  previousText: string,
  afterText: string,
}
After
1
import { type ReposConfiguration } from &#39;./configTypes.ts&#39;
src/helpers.ts:82
Before
82 83
const getLocation = (reposConfig: any, branchName: string, repoName: string): string => {
  NavValues,
After
82
const getLocation = (reposConfig: ReposConfiguration, repoName: string): string => {
src/paginatedPatches.ts:1
Before
1 2
let paginatedPatches = null
export default async (repos) => {
After
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>) => {
src/paginatedPatches.ts:15
Before
15
        && page.patches.length <= patchesPerPage
After
15
        && page.commits.length <= patchesPerPage
src/paginatedPatches.ts:24
Before
24 25
        patches: [patch.patch],
      paginatedPatches[index].patches.push(patch.patch)
After
24 25
        commits: [patch.commit],
      paginatedPatches[index].commits.push(patch.commit)
src/repos.ts:3
Before
3
After
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)
src/repos.ts:30
Before
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: [],
After
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
src/vcses/git/operations.ts:4
Before
4
export const getFileList = async (repoName: string, branchName: string, repoLocation: string) => {
After
4
export const getFileList = async (branchName: string, repoLocation: string) => {
src/vcses/git/operations.ts:41
Before
41
After
41
  let previousHash: null | string = null
src/vcses/git/operations.ts:54
Before
54
        break
After
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
src/vcses/git/operations.ts:83
Before
83 84 85
                  diffs,
                  parent: "todo",
export const getFileLastTouchInfo = async (repo: string, branch: string, filename: string, repoLocation: string) => {
After
83 84 85
        diffs,
        parent: null,
export const getFileLastTouchInfo = async (branch: string, filename: string, repoLocation: string) => {
src/vcses/operations.ts:6
Before
6
    getFileLastTouchInfo: (repoName: string, branchName: string, filename: string, repoLocation: string) => Promise<Array<{sha: string, author: string}>>,
After
6
    getFileLastTouchInfo: (branchName: string, filename: string, repoLocation: string) => Promise<Array<{sha: string, author: string}>>,
templates/branches.njk:1
Before
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>
After
1
  <li><a href="{{reposPath}}/{{branch.repoName | slugify}}/branches/{{branch.branchName | slugify}}">{{branch.branchName}}</a>{% if branch.branchName == branchInfo.branchName %} (current){% endif %}</li>
templates/patch.njk:1
Before
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>
After
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>
templates/patch.njk:24
Before
24
  {% set patchHunks = patchInfo.patch.diffs %}
After
24
  {% set patchHunks = patchInfo.commit.diffs %}
templates/patches.njk:9
Before
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>
After
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>