Change references of "branches" to "rels", allow for tags, too

b30bd9fa7e0bc1ed9e557769a79dcff79458c83d

Tucker McKnight <tucker@pangolin.lan> | Sun Mar 01 2026

Change references of "branches" to "rels", allow for tags, too

"rels" refers to a branch _or_ a tag. Flattened data lists
(flatPatches, flatFiles, and branches.ts (now flatRels.ts)) should
specify which type of rel each of their entries is.

Pages now have the rel type (branch or tag) in their permalink
instead of always being hard-coded to /branches/.
js_templates/branches.ts:8
Before
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  data: any,
) => {
  const slugify = eleventyConfig.getFilter("slugify")
  const nav = NavHelper(reposConfig, slugify, data.branchInfo.repoName, data.branchInfo.branchName)

  const branchesWithWorkInProgress = data.branches.filter(branch => branch.ahead > 0)
  const branchesFullyMerged = data.branches.filter(branch => branch.ahead === 0)

  const branchCards = (branches) => {
    return m('ul', branches.map((branch) => {
      return branch.repoName === data.branchInfo.repoName ?
        m('li', [
          m('a', {
            href: `${data.reposPath}/${slugify(branch.repoName)}/branches/${slugify(branch.branchName)}/branches`
          }, branch.branchName),
          branch.branchName === data.branchInfo.branchName
            ? m('div', {class: "badge rounded-pill bg-secondary mx-1"}, 'current') : null,
          branch.branchName === data.reposConfig.repos[branch.repoName].defaultBranch
            ? m('div', {class: "badge rounded-pill bg-info text-dark mx-1"}, 'default') : null,
          m('ul', [
            m('li', [
After
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  data: any,
) => {
  const slugify = eleventyConfig.getFilter("slugify")
  const nav = NavHelper(reposConfig, slugify, data.flatRel.repoName, data.flatRel.relName)

  const branchesWithWorkInProgress = data.flatRels.filter(rel => rel.type === "branch" && rel.ahead > 0)
  const branchesFullyMerged = data.flatRels.filter(rel => rel.type === "branch" && rel.ahead === 0)

  const branchCards = (branches) => {
    return m('ul', branches.map((branch) => {
      return branch.repoName === data.flatRel.repoName ?
        m('li', [
          m('a', {
            href: `${data.reposPath}/${slugify(branch.repoName)}/branches/${slugify(branch.relName)}/branches`
          }, branch.relName),
          branch.relName === data.flatRel.relName
            ? m('div', {class: "badge rounded-pill bg-secondary mx-1"}, 'current') : null,
          branch.relName === data.reposConfig.repos[branch.repoName].defaultBranch
            ? m('div', {class: "badge rounded-pill bg-info text-dark mx-1"}, 'default') : null,
          m('ul', [
            m('li', [
js_templates/commits.ts:7
Before
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  eleventyConfig: any,
  data: any,
) => {
  const pagesJustForBranch = eleventyConfig.getFilter("pagesJustForBranch")
  const slugify = eleventyConfig.getFilter("slugify")
  const date = eleventyConfig.getFilter("date")

  const nav = NavHelper(reposConfig, slugify, data.patchPage.repoName, data.patchPage.branchName)

  const pageContent = [
    m('div', {class: "row mt-3 mb-1"},
      m('div', {class: "col"},
        m('p', {class: "d-inline-block"}, [
          'Showing commits from ',
          m('span', {class: "font-monospace me-2"}, data.patchPage.branchName),
          m('a', {
            class: "btn btn-outline-primary badge shadow-none",
            href: nav.repoCurrentBranchRssFeed()
After
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  eleventyConfig: any,
  data: any,
) => {
  const pagesJustForRel = eleventyConfig.getFilter("pagesJustForRel")
  const slugify = eleventyConfig.getFilter("slugify")
  const date = eleventyConfig.getFilter("date")

  const nav = NavHelper(reposConfig, slugify, data.patchPage.repoName, data.patchPage.relName)

  const pageContent = [
    m('div', {class: "row mt-3 mb-1"},
      m('div', {class: "col"},
        m('p', {class: "d-inline-block"}, [
          'Showing commits from ',
          m('span', {class: "font-monospace me-2"}, data.patchPage.relName),
          m('a', {
            class: "btn btn-outline-primary badge shadow-none",
            href: nav.repoCurrentBranchRssFeed()
js_templates/commits.ts:34
Before
33
34
35
36
37
38
39

40
41
42
43
44
45
46
    ),
    m('nav', 
      m('ul', {class: "pagination"},
        pagesJustForBranch(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.branchName
⁣
        ).map((pageObj) => {
          return m('li', {class: "page-item"},
            m('a', {
              class: `page-link ${pageObj.pageNumber === data.patchPage.pageNumber ? 'active' : ''}`,
              href: `${data.reposPath}/${slugify(data.patchPage.repoName)}/branches/${data.patchPage.branchName}/commits/page${pageObj.pageNumber}`
            }, pageObj.pageNumber)
          )
        })
After
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    ),
    m('nav', 
      m('ul', {class: "pagination"},
        pagesJustForRel(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.relName,
          data.patchPage.type,
        ).map((pageObj) => {
          return m('li', {class: "page-item"},
            m('a', {
              class: `page-link ${pageObj.pageNumber === data.patchPage.pageNumber ? 'active' : ''}`,
              href: `${data.reposPath}/${slugify(data.patchPage.repoName)}/${data.patchPage.type}/${data.patchPage.relName}/commits/page${pageObj.pageNumber}`
            }, pageObj.pageNumber)
          )
        })
js_templates/commits.ts:56
Before
55
56
57
58
59
60
        commit.isMerge ? m('span', {class: 'badge rounded-pill bg-primary me-1'}, 'merge') : null,
        m('a', {
          class: "fs-5",
          href: `${data.reposPath}/${slugify(data.patchPage.repoName)}/branches/${slugify(data.patchPage.branchName)}/commits/${commit.hash}`,
        }, commit.message.split('\n').slice(0, 1)),
        m('br'),
        m('span', date(commit.date)),
After
55
56
57
58
59
60
        commit.isMerge ? m('span', {class: 'badge rounded-pill bg-primary me-1'}, 'merge') : null,
        m('a', {
          class: "fs-5",
          href: `${data.reposPath}/${slugify(data.patchPage.repoName)}/${data.patchPage.type}/${slugify(data.patchPage.relName)}/commits/${commit.hash}`,
        }, commit.message.split('\n').slice(0, 1)),
        m('br'),
        m('span', date(commit.date)),
js_templates/commits.ts:67
Before
66
67
68
69
70
71
72

73
74
75
76
77
78
79
    })),
    m('nav',
      m('ul', {class: "pagination"},
        pagesJustForBranch(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.branchName
⁣
        ).map((pageObj) => {
          return m('li', {class: "page-item"},
            m('a', {
              class: `page-link ${pageObj.pageNumber === data.patchPage.pageNumber ? 'active' : ''}`,
              href: `${data.reposPath}/${slugify(data.patchPage.repoName)}/branches/${data.patchPage.branchName}/commits/page${pageObj.pageNumber}`
            }, pageObj.pageNumber)
          )
        })
After
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    })),
    m('nav',
      m('ul', {class: "pagination"},
        pagesJustForRel(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.relName,
          data.patchPage.type,
        ).map((pageObj) => {
          return m('li', {class: "page-item"},
            m('a', {
              class: `page-link ${pageObj.pageNumber === data.patchPage.pageNumber ? 'active' : ''}`,
              href: `${data.reposPath}/${slugify(data.patchPage.repoName)}/${data.patchPage.type}/${data.patchPage.relName}/commits/page${pageObj.pageNumber}`
            }, pageObj.pageNumber)
          )
        })
js_templates/common/htmlPage.ts:11
Before
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  }

  const repo: Repository = data.currentRepo
  const branch: Repository['branches'][0] = data.currentBranch

  const slugify = eleventyConfig.getFilter("slugify")
  const nav = NavHelper(reposConfig, slugify, repo.name, branch.name)

  const branchesWithHrefs = repo.branches.map((branch) => {
    return {
      name: branch.name,
      href: nav.repoBranchHome(branch.name) + '/' + data.nav.path,
      date: repo.commits.get(branch.head).date.toISOString(),
    }
    }).concat(repo.tags.map((tag) => {
      return {
After
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  }

  const repo: Repository = data.currentRepo
  const rel: Repository['branches'][0] = data.currentRel

  const slugify = eleventyConfig.getFilter("slugify")
  const nav = NavHelper(reposConfig, slugify, repo.name, rel.name)

  const branchesWithHrefs = repo.branches.map((branch) => {
    return {
      name: branch.name,
      href: nav.repoBranchHome(branch.name) + '/' + data.nav.path,
      date: repo.commits.get(branch.sha).date.toISOString(),
    }
    }).concat(repo.tags.map((tag) => {
      return {
js_templates/common/htmlPage.ts:39
Before
38
39
40
41
42
43
      m('script', m.trust(`
        window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
        window.defaultBranch = "${repo.defaultBranch}";
        window.currentBranch = "${branch.name}";
        window.cloneUrl = "${repo.cloneUrl}";
      `)),
      m('link', {
After
38
39
40
41
42
43
      m('script', m.trust(`
        window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
        window.defaultBranch = "${repo.defaultBranch}";
        window.currentBranch = "${rel.name}";
        window.cloneUrl = "${repo.cloneUrl}";
      `)),
      m('link', {
js_templates/common/htmlPage.ts:71
Before
70
71
72
73
74
75
              'data-bs-toggle': "dropdown",
              'data-bs-auto-close': "outside",
              'aria-expanded': "false"
            }, branch.name),
            m('div', {class: "dropdown-menu"}, [
              m('form', {class: "mx-3 my-1"}, [
                m('input', {type: "text", class: "form-control", id: "dropdownBranchSearch", placeholder: "Search branches..."}),
After
70
71
72
73
74
75
              'data-bs-toggle': "dropdown",
              'data-bs-auto-close': "outside",
              'aria-expanded': "false"
            }, rel.name),
            m('div', {class: "dropdown-menu"}, [
              m('form', {class: "mx-3 my-1"}, [
                m('input', {type: "text", class: "form-control", id: "dropdownBranchSearch", placeholder: "Search branches..."}),
js_templates/common/htmlPage.ts:95
Before
94
95
96
97
98
99
              ]),
              m('div', {class: "dropdown-divider"}),
              m('div', {id: "dropdown-branches-results", class: "dropdown-branches"},
                branchesListItems(branchesWithHrefs, repo.defaultBranch, branch.name, 'date')
              )
            ])
          ])
After
94
95
96
97
98
99
              ]),
              m('div', {class: "dropdown-divider"}),
              m('div', {id: "dropdown-branches-results", class: "dropdown-branches"},
                branchesListItems(branchesWithHrefs, repo.defaultBranch, rel.name, 'date')
              )
            ])
          ])
js_templates/feed.ts:1
Before
0
1
2
3
4
5
import m from 'mithril'
import render from 'mithril-node-render'
import { type Repository } from '../src/dataTypes.ts'
import branches from '../src/branches.ts'
import { dateToRfc3339 } from '@11ty/eleventy-plugin-rss'
import flatPatches from '../src/flatPatches.ts'
After
0
1
2
3
4
5
import m from 'mithril'
import render from 'mithril-node-render'
import { type Repository } from '../src/dataTypes.ts'
import getFlatRels from '../src/flatRels.ts'
import { dateToRfc3339 } from '@11ty/eleventy-plugin-rss'
import flatPatches from '../src/flatPatches.ts'
js_templates/feed.ts:9
Before
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
  eleventyConfig: any,
) => {
  return (data) => {
    const branch: ReturnType<typeof branches>[0] = data.branch
    const currentRepo: Repository = data.currentRepo
    const currentBranch: Repository['branches'][0] = data.currentBranch
    const currentBranchCommits: Awaited<ReturnType<typeof flatPatches>> = data.currentBranchCommits

    const slugify = eleventyConfig.getFilter("slugify")

    return render([
      m.trust('<?xml version="1.0" encoding="utf-8"?>'),
      m('feed', {xmlns: "http://www.w3.org/2005/Atom"}, [
        m('title', `Latest patches in ${branch.branchName}`),
        m.trust(`<link href="${ data.reposConfig.baseUrl + '/repos/' + slugify(branch.repoName) + '/branches/' + slugify(branch.branchName) + '/commits.xml'}" rel="self" />`),
        m.trust(`<link href="${data.reposConfig.baseUrl + '/repos/' + slugify(branch.repoName) + '/branches/' + slugify(branch.branchName)}" />`),
        m('updated', dateToRfc3339(currentRepo.commits.get(currentBranch.head).date)),
        m('id', data.reposConfig.baseUrl),
        m('author',
          m('name', `${currentRepo.name} contributors`)
        ),
        currentBranchCommits.map((commit) => {
          const commitUrl = data.reposConfig.baseUrl + '/repos/' + slugify(branch.repoName) + '/branches/' + slugify(branch.branchName) + '/commits/' + commit.commit.hash
          return m('entry', [
            m('title', commit.commit.message.split('\n')[0]),
            m('author', m('name', commit.commit.author)),
After
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
  eleventyConfig: any,
) => {
  return (data) => {
    const flatRel: ReturnType<typeof getFlatRels>[0] = data.flatRel
    const currentRepo: Repository = data.currentRepo
    const currentRel: Repository['branches'][0] = data.currentRel
    const currentRelCommits: Awaited<ReturnType<typeof flatPatches>> = data.currentRelCommits

    const slugify = eleventyConfig.getFilter("slugify")

    return render([
      m.trust('<?xml version="1.0" encoding="utf-8"?>'),
      m('feed', {xmlns: "http://www.w3.org/2005/Atom"}, [
        m('title', `Latest patches in ${flatRel.relName}`),
        m.trust(`<link href="${ data.reposConfig.baseUrl + '/repos/' + slugify(flatRel.repoName) + `/${flatRel.type}/` + slugify(flatRel.relName) + '/commits.xml'}" rel="self" />`),
        m.trust(`<link href="${data.reposConfig.baseUrl + '/repos/' + slugify(flatRel.repoName) + `/${flatRel.type}/` + slugify(flatRel.relName)}" />`),
        m('updated', dateToRfc3339(currentRepo.commits.get(currentRel.sha).date)),
        m('id', data.reposConfig.baseUrl),
        m('author',
          m('name', `${currentRepo.name} contributors`)
        ),
        currentRelCommits.map((commit) => {
          const commitUrl = data.reposConfig.baseUrl + '/repos/' + slugify(flatRel.repoName) + `/${flatRel.type}/` + slugify(flatRel.relName) + '/commits/' + commit.commit.hash
          return m('entry', [
            m('title', commit.commit.message.split('\n')[0]),
            m('author', m('name', commit.commit.author)),
js_templates/file.ts:15
Before
14
15
16
17
18
19
  const languageExtension = eleventyConfig.getFilter("languageExtension")
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")

  const currentBranch: Branch = data.currentBranch
  const fileInfo: FlatFileEntry = data.fileInfo

  const pageContent = [  
After
14
15
16
17
18
19
  const languageExtension = eleventyConfig.getFilter("languageExtension")
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")

  const currentRel: Branch = data.currentRel
  const fileInfo: FlatFileEntry = data.fileInfo

  const pageContent = [  
js_templates/file.ts:96
Before
95
96
97
98
99
100
            m('div', {class: "row rendered-content"},
              m('div', {class: "col"},
                m.trust(await renderContentIfAvailable(
                  currentBranch.fileList.get(fileInfo.file).fileInfo.contents
                ))
              )
            )
After
95
96
97
98
99
100
            m('div', {class: "row rendered-content"},
              m('div', {class: "col"},
                m.trust(await renderContentIfAvailable(
                  currentRel.fileList.get(fileInfo.file).fileInfo.contents
                ))
              )
            )
js_templates/file.ts:116
Before
115
116
117
118
119
120
              m('div', {class: "col-auto p-0"},
                m('code', {style: "white-space: pre;"},
                  m('pre', {class: "language-text"},
                    lineNumbers(currentBranch.fileList.get(fileInfo.file).fileInfo.contents).map((lineNumber) => {
                      return lineNumber
                    }).join('\n')
                  )
After
115
116
117
118
119
120
              m('div', {class: "col-auto p-0"},
                m('code', {style: "white-space: pre;"},
                  m('pre', {class: "language-text"},
                    lineNumbers(currentRel.fileList.get(fileInfo.file).fileInfo.contents).map((lineNumber) => {
                      return lineNumber
                    }).join('\n')
                  )
js_templates/file.ts:125
Before
124
125
126
127
128
129
130
131
132
133
134
135
136
              m('div', {id: "annotations", class: "col-auto d-none p-0"},
                m('code', {style: "white-space: pre;"}, [
                  m('pre', {class: "language-text"}, m.trust(
                    currentBranch.fileList.get(fileInfo.file).fileInfo.blameLines.map((annotation) => {
                      return `<a href="${data.reposPath}/${slugify(fileInfo.repoName)}/branches/${slugify(fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
                    }).join('\n')))
                ])
              ),
              m('div', {class: "col overflow-scroll p-0"},
                m('code', m.trust(highlightCode(
                  currentBranch.fileList.get(fileInfo.file).fileInfo.contents,
                  languageExtension(
                    fileInfo.file,
                    fileInfo.repoName
After
124
125
126
127
128
129
130
131
132
133
134
135
136
              m('div', {id: "annotations", class: "col-auto d-none p-0"},
                m('code', {style: "white-space: pre;"}, [
                  m('pre', {class: "language-text"}, m.trust(
                    currentRel.fileList.get(fileInfo.file).fileInfo.blameLines.map((annotation) => {
                      return `<a href="${data.reposPath}/${slugify(fileInfo.repoName)}/branches/${slugify(fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
                    }).join('\n')))
                ])
              ),
              m('div', {class: "col overflow-scroll p-0"},
                m('code', m.trust(highlightCode(
                  currentRel.fileList.get(fileInfo.file).fileInfo.contents,
                  languageExtension(
                    fileInfo.file,
                    fileInfo.repoName
js_templates/files.ts:3
Before
2
3
4
5
6
7
import htmlPage from './common/htmlPage.ts'

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const branch: Repository['branches'][0] = data.currentBranch
  const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")
  const slugify = eleventyConfig.getFilter("slugify")
After
2
3
4
5
6
7
import htmlPage from './common/htmlPage.ts'

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const branch: Repository['branches'][0] = data.currentRel
  const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")
  const slugify = eleventyConfig.getFilter("slugify")
js_templates/files.ts:14
Before
13
14
15
16
17
18
      m('div', {class: "col"},
        m('p', [
          'Files snapshot from ',
          m('span', {class: "font-monospace"}, data.branchInfo.branchName)
        ])
      )
    ]),
After
13
14
15
16
17
18
      m('div', {class: "col"},
        m('p', [
          'Files snapshot from ',
          m('span', {class: "font-monospace"}, data.flatRel.relName)
        ])
      )
    ]),
js_templates/files.ts:27
Before
26
27
28
29
30
31
      return m('li', {class: 'list-group-item'}, [
        file.isDirectory ? m.trust('<span>&#x1F4C1;&nbsp;</span>') : null,
        m('a', {
          href: `${data.reposPath}/${slugify(data.branchInfo.repoName)}/branches/${slugify(data.branchInfo.branchName)}/files/${
            file.fullPath.split('/')
            .map((pathPart) => {
              return pathPart.split('.').map((subPart) => {
After
26
27
28
29
30
31
      return m('li', {class: 'list-group-item'}, [
        file.isDirectory ? m.trust('<span>&#x1F4C1;&nbsp;</span>') : null,
        m('a', {
          href: `${data.reposPath}/${slugify(data.flatRel.repoName)}/branches/${slugify(data.flatRel.relName)}/files/${
            file.fullPath.split('/')
            .map((pathPart) => {
              return pathPart.split('.').map((subPart) => {
js_templates/raw.ts:3
Before
2
3
4
5
6
7

export default async (eleventyConfig: any) => {
  return async (data) => {
    const branch: Branch = data.currentBranch

    return branch.fileList.get(data.fileInfo.file).fileInfo.contents
  }
After
2
3
4
5
6
7

export default async (eleventyConfig: any) => {
  return async (data) => {
    const branch: Branch = data.currentRel

    return branch.fileList.get(data.fileInfo.file).fileInfo.contents
  }
js_templates/repo.ts:5
Before
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const repo: Repository = data.currentRepo
  const branch: Repository['branches'][0] = data.currentBranch
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
  const slugify = eleventyConfig.getFilter("slugify")
  const getReadMe = eleventyConfig.getFilter("getReadMe")
  const latestCommit = repo.commits.get(branch.head)
  const latestCommitMessage = latestCommit.message.length > 72
    ? latestCommit.message.split('\n')[0].substr(0, 72) + '...'
    : latestCommit.message

  const nav = NavHelper(reposConfig, slugify, repo.name, branch.name)

  const languageCounts = Array.from(branch.fileList.keys()).reduce((counts, currentFile) => {
    const fileParts = currentFile.split(".")
    const fileExtension = fileParts[fileParts.length - 1]
// todo: add more ignoreable extensions or specific files
After
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const repo: Repository = data.currentRepo
  const rel: Repository['branches'][0] | Repository['tags'][0] = data.currentRel
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
  const slugify = eleventyConfig.getFilter("slugify")
  const getReadMe = eleventyConfig.getFilter("getReadMe")
  const latestCommit = repo.commits.get(rel.sha)
  const latestCommitMessage = latestCommit.message.length > 72
    ? latestCommit.message.split('\n')[0].substr(0, 72) + '...'
    : latestCommit.message

  const nav = NavHelper(reposConfig, slugify, repo.name, rel.name)

  const languageCounts = Array.from(rel.fileList.keys()).reduce((counts, currentFile) => {
    const fileParts = currentFile.split(".")
    const fileExtension = fileParts[fileParts.length - 1]
// todo: add more ignoreable extensions or specific files
js_templates/repo.ts:31
Before
30
31
32
33
34
35

  // todo: this is probably broken for repos that use fewer than 6 languages
  let languagePercentages: Array<[string, number]> = []
  const total = Array.from(branch.fileList.keys()).length

  for (const entry of languageCounts) {
    languagePercentages.push([entry[0], entry[1] / total])
After
30
31
32
33
34
35

  // todo: this is probably broken for repos that use fewer than 6 languages
  let languagePercentages: Array<[string, number]> = []
  const total = Array.from(rel.fileList.keys()).length

  for (const entry of languageCounts) {
    languagePercentages.push([entry[0], entry[1] / total])
js_templates/repo.ts:46
Before
45
46
47
48
49
50

  const largestPercent = Math.max(...topLanguagePercentages.map(tuple => tuple[1]), otherLanguagePercent)

  const readmeContent = await renderContentIfAvailable(await getReadMe(repo.name, branch.name), branch.name)

  const pageContent = [
    m('div', {class: "row"}, [
After
45
46
47
48
49
50

  const largestPercent = Math.max(...topLanguagePercentages.map(tuple => tuple[1]), otherLanguagePercent)

  const readmeContent = await renderContentIfAvailable(await getReadMe(repo.name, rel.name), rel.name)

  const pageContent = [
    m('div', {class: "row"}, [
main.ts:2
Before
1
2
3
4
5
6
import util from 'util'
import childProcess from 'child_process'
import {repos, getBranchesAndTags} from './src/repos.ts'
import branches from './src/branches.ts'
import flatFiles from './src/flatFiles.ts'
import flatPatches from './src/flatPatches.ts'
import paginatedPatches, {type PatchPage} from './src/paginatedPatches.ts'
After
1
2
3
4
5
6
import util from 'util'
import childProcess from 'child_process'
import {repos, getBranchesAndTags} from './src/repos.ts'
import getFlatRels from './src/flatRels.ts'
import flatFiles from './src/flatFiles.ts'
import flatPatches from './src/flatPatches.ts'
import paginatedPatches, {type PatchPage} from './src/paginatedPatches.ts'
main.ts:88
Before
87
88
89
90
91
92
93
  eleventyConfig.addGlobalData("reposConfig", reposConfiguration)
  eleventyConfig.addGlobalData("reposPath", reposPath)

  const branchesData = branches(reposData)
  eleventyConfig.addGlobalData("branches", branchesData)

  eleventyConfig.addFilter("getFileName", (filePath: string) => {
    const pathParts = filePath.split("/")
After
87
88
89
90
91
92
93
  eleventyConfig.addGlobalData("reposConfig", reposConfiguration)
  eleventyConfig.addGlobalData("reposPath", reposPath)

  const flatRels = getFlatRels(reposData)
  eleventyConfig.addGlobalData("flatRels", flatRels)

  eleventyConfig.addFilter("getFileName", (filePath: string) => {
    const pathParts = filePath.split("/")
main.ts:253
Before
252
253
254
255
256
257
258
    return isDirectory
  })

  eleventyConfig.addFilter("pagesJustForBranch", (pages: Array<PatchPage>, repoName: string, branchName: string) => {
    return pages.filter(page => page.repoName === repoName && page.branchName === branchName)
  })

  eleventyConfig.addFilter("date", (dateString: string) => {
After
252
253
254
255
256
257
258
    return isDirectory
  })

  eleventyConfig.addFilter("pagesJustForRel", (pages: Array<PatchPage>, repoName: string, relName: string, relType: "branch" | "tag") => {
    return pages.filter(page => page.repoName === repoName && page.relName === relName && page.type === relType)
  })

  eleventyConfig.addFilter("date", (dateString: string) => {
main.ts:295
Before
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314


315
316

317
318
319

320
321
    commonPage(branchesJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "branches",
        size: 1,
        alias: "branchInfo",
      },
      permalink: (data) => {
        const repoName = data.branchInfo.repoName
        const branchName = data.branchInfo.branchName
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/branches/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.branchInfo.repoName,
          branchName: (data) => data.branchInfo.branchName,
          path: "branches"
        },
        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
        }),
⁣
      },
      navTab: "branches",
    }
After
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    commonPage(branchesJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/branches/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRel.repoName,
          relName: (data) => data.flatRel.relName,
          path: "branches"
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          const currentRepo = reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })
          return currentRepo[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        }
      },
      navTab: "branches",
    }
main.ts:338
Before
337
338
339

340
341
342
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/files/${data.fileInfo.file.split('/').map((filePart) => filePart.split('.').map((subPart) => eleventyConfig.getFilter("slugify")(subPart)).join('.')).join('/')}.html`
      },
      eleventyComputed: {
        nav: {
After
337
338
339
340
341
342
343
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
        const relType = data.fileInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(branchName)}/files/${data.fileInfo.file.split('/').map((filePart) => filePart.split('.').map((subPart) => eleventyConfig.getFilter("slugify")(subPart)).join('.')).join('/')}.html`
      },
      eleventyComputed: {
        nav: {
main.ts:349
Before
348
349
350
351
352
353
        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
After
348
349
350
351
352
353
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }),
        currentRel: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }).branches.find(branch => {
          return branch.name === data.fileInfo.branchName
main.ts:374
Before
373
374
375

376
377
378
379
380
381
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/raw/${data.fileInfo.file.split('.').map(filePart => eleventyConfig.getFilter("slugify")(filePart)).join('.')}`
      },
      eleventyComputed: {
        currentBranch: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }).branches.find(branch => {
          return branch.name === data.fileInfo.branchName
After
373
374
375
376
377
378
379
380
381
382
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
        const relType = data.fileInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(branchName)}/raw/${data.fileInfo.file.split('.').map(filePart => eleventyConfig.getFilter("slugify")(filePart)).join('.')}`
      },
      eleventyComputed: {
        currentRel: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }).branches.find(branch => {
          return branch.name === data.fileInfo.branchName
main.ts:392
Before
391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411


412
413
414
415
416

417
418
    commonPage(filesJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "branches",
        size: 1,
        alias: "branchInfo",
      },
      permalink: (data) => {
        const repoName = data.branchInfo.repoName
        const branchName = data.branchInfo.branchName
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/files/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.branchInfo.repoName,
          branchName: (data) => data.branchInfo.branchName,
          path: "files",
        },
        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
        })
⁣
      },
      navTab: "files",
    }
After
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
    commonPage(filesJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/files/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRel.repoName,
          relName: (data) => data.flatRel.relName,
          path: "files",
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        }
      },
      navTab: "files",
    }
main.ts:426
Before
425
426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445


446
447
448
449
450

451
452
    commonPage(repoJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "branches",
        size: 1,
        alias: "branch",
      },
      permalink: (data) => {
        const repoName = data.branch.repoName
        const branchName = data.branch.branchName
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.branch.repoName,
          branchName: (data) => data.branch.branchName,
          path: (data) => '', // ask about why empty string here shows up as a function
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.branch.repoName
        }),
⁣
⁣
        currentBranch: (data) => reposData.find(repo => {
          return repo.name === data.branch.repoName
        }).branches.find(branch => {
          return branch.name === data.branch.branchName
        }),
⁣
      },
      navTab: "home"
    }
After
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
    commonPage(repoJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRel.repoName,
          relName: (data) => data.flatRel.relName,
          path: (data) => '', // TODO: ask about why empty string here shows up as a function
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        }
      },
      navTab: "home"
    }
main.ts:457
Before
456
457
458
459
460
461
  // COMMITS.TS
  const paginatedPatchesData = await paginatedPatches(reposData)
  eleventyConfig.addTemplate(
    `repos/patches.11ty.js`,
    commonPage(commitsJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
After
456
457
458
459
460
461
  // COMMITS.TS
  const paginatedPatchesData = await paginatedPatches(reposData)
  eleventyConfig.addTemplate(
    `repos/commits.11ty.js`,
    commonPage(commitsJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
main.ts:468
Before
467
468
469
470

471
472
473
474
475
476
477
478
479
480
481


482
483
484
485
486

487
488
      paginatedPatches: paginatedPatchesData,
      permalink: (data) => {
        const repoName = data.patchPage.repoName
        const branchName = data.patchPage.branchName
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/commits/page${data.patchPage.pageNumber}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.patchPage.repoName,
          branchName: (data) => data.patchPage.branchName,
          path: 'commits/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
        }),
⁣
      },
      navTab: "commits",
    }
After
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
      paginatedPatches: paginatedPatchesData,
      permalink: (data) => {
        const repoName = data.patchPage.repoName
        const relName = data.patchPage.relName
        const relType = data.patchPage.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/commits/page${data.patchPage.pageNumber}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.patchPage.repoName,
          relName: (data) => data.patchPage.relName,
          path: 'commits/page1',
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.patchPage.repoName
        }),
        currentRel: (data) => {
          const relType = data.patchPage.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.patchPage.repoName
          })[relType].find(rel => {
            return rel.name === data.patchPage.relName
          })
        }
      },
      navTab: "commits",
    }
main.ts:504
Before
503
504
505
506

507
508
509
510
511
512
513
514
515
516
517


518
519
520
521

522
523
524
      flatPatches: flatPatchesData,
      permalink: (data) => {
        const repoName = data.patchInfo.repoName
        const branchName = data.patchInfo.branchName
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/commits/${data.patchInfo.commit.hash}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.patchInfo.repoName,
          branchName: (data) => data.patchInfo.branchName,
          path: 'commits/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        }),
      },
      navTab: "commits",
    }
After
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
      flatPatches: flatPatchesData,
      permalink: (data) => {
        const repoName = data.patchInfo.repoName
        const relName = data.patchInfo.relName
        const relType = data.patchInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/commits/${data.patchInfo.commit.hash}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.patchInfo.repoName,
          relName: (data) => data.patchInfo.relName,
          path: 'commits/page1',
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.patchInfo.repoName
        }),
        currentRel: (data) => {
          const relType = data.patchInfo.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.patchInfo.repoName
          })[relType].find(rel => {
            return rel.name === data.patchInfo.relName
          })
        },
      },
      navTab: "commits",
    }
main.ts:532
Before
531
532
533
534
535
536
537
538
539
540

541
542
543
544
545
546


547
548
549
550

551
552
553
554
555
556
    feedJsTemplate(eleventyConfig),
    {
      pagination: {
        data: "branches",
        size: 1,
        alias: "branch",
      },
      permalink: (data) => {
        const repoName = data.branch.repoName
        const branchName = data.branch.branchName
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/commits.xml`
      },
      eleventyComputed: {
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.branch.repoName
        }),
⁣
⁣
        currentBranch: (data) => reposData.find(repo => {
          return repo.name === data.branch.repoName
        }).branches.find(branch => {
          return branch.name === data.branch.branchName        }),
        currentBranchCommits: (data) => {
          return flatPatchesData.filter((patch) => {
            return patch.branchName === data.branch.branchName
          })
        }
      },
After
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
    feedJsTemplate(eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/commits.xml`
      },
      eleventyComputed: {
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        },
        currentRelCommits: (data) => {
          return flatPatchesData.filter((patch) => {
            return patch.relName === data.flatRel.relName
          })
        }
      },
src/branches.ts:1
Before
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { type Repository } from "./dataTypes.ts"

let cachedBranches: Array<{
  branchName: string,
  repoName: string,
}> | null = null

export default (repos: Array<Repository>) => {
  if (cachedBranches !== null) { return cachedBranches }

  cachedBranches = repos.flatMap((repo) => {
    return repo.branches.map((branch) => {
      const result = {
        branchName: branch.name,
        repoName: repo.name,
        compareTo: branch.compareTo,
        ahead: branch.ahead,
        behind: branch.behind,
      }
      if (branch.description) { result['description'] = branch.description }
      return result
    })
  })

  return cachedBranches
}
After























⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
src/dataTypes.ts:17
Before
16
17
18
19
20
21
    ahead: number,
    behind: number,
    compareTo: string,
    head: string,
    // instead of strings, make it point to a function that returns
    // the file contents. The first time, search in both directions for a commit
    // that has already cached this file before a diff in that commit mentions
After
16
17
18
19
20
21
    ahead: number,
    behind: number,
    compareTo: string,
    sha: string,
    // instead of strings, make it point to a function that returns
    // the file contents. The first time, search in both directions for a commit
    // that has already cached this file before a diff in that commit mentions
src/flatPatches.ts:3
Before
2
3
4
5

6
7
type FlatPatchRecord = {
  commit: ReturnType<Repository['commits']['get']>,
  repoName: string,
  branchName: string,
⁣
}

let cachedFlatPatches: Array<FlatPatchRecord> | null = null
After
2
3
4
5
6
7
8
type FlatPatchRecord = {
  commit: ReturnType<Repository['commits']['get']>,
  repoName: string,
  relName: string,
  type: "branch" | "tag",
}

let cachedFlatPatches: Array<FlatPatchRecord> | null = null
src/flatPatches.ts:13
Before
12
13
14
15
16
17
18
19
20

21
22
23
24
25
  if (cachedFlatPatches !== null) { return cachedFlatPatches }

  cachedFlatPatches = repos.flatMap((repo) => {
    return repo.branches.flatMap((branch) => {
      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)
After
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  if (cachedFlatPatches !== null) { return cachedFlatPatches }

  cachedFlatPatches = repos.flatMap((repo) => {
    const branches = repo.branches.flatMap((branch) => {
      const flatPatches: Array<FlatPatchRecord> = []
      let currentCommit: ReturnType<Repository['commits']['get']> | undefined = repo.commits.get(branch.sha)

      while (currentCommit !== undefined) {
        flatPatches.push({
          type: "branch",
          commit: currentCommit,
          repoName: repo.name,
          relName: branch.name
        })

        currentCommit = repo.commits.get(currentCommit.parent)
src/flatPatches.ts:29
Before
28
29
30



















31
32

      return flatPatches
    })
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
  })

  return cachedFlatPatches
After
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

      return flatPatches
    })

    const tags = repo.tags.flatMap((tag) => {
      const flatPatches: Array<FlatPatchRecord> = []
      let currentCommit: ReturnType<Repository['commits']['get']> = repo.commits.get(tag.sha)
      while (currentCommit !== undefined) {
        flatPatches.push({
          type: "tag",
          commit: currentCommit,
          repoName: repo.name,
          relName: tag.name,
        })

        currentCommit = repo.commits.get(currentCommit.parent)
      }

      return flatPatches
    })

    return [...branches, ...tags]
  })

  return cachedFlatPatches
src/flatRels.ts:0
Before













































⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
After
-1
0
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
import { type Repository } from "./dataTypes.ts"

type BranchEntry = {
  relName: string,
  type: "branch",
  repoName: string,
  compareTo: string,
  ahead: number,
  behind: number,
}

type TagEntry = {
  relName: string,
  type: "tag",
  repoName: string,
}

let cachedRels: Array<BranchEntry | TagEntry> | null = null

export default (repos: Array<Repository>) => {
  if (cachedRels !== null) { return cachedRels }

  cachedRels = repos.flatMap((repo) => {
    const branches: Array<BranchEntry> = repo.branches.map((branch) => {
      const result: BranchEntry = {
        relName: branch.name,
        type: "branch",
        repoName: repo.name,
        compareTo: branch.compareTo,
        ahead: branch.ahead,
        behind: branch.behind,
      }
      if (branch.description) { result['description'] = branch.description }
      return result
    })
    const tags: Array<TagEntry> = repo.tags.map((tag) => {
      return {
        relName: tag.name,
        type: "tag",
        repoName: repo.name,
      }
    })

    return [...branches, ...tags]
  })

  return cachedRels
}
src/paginatedPatches.ts:3
Before
2
3
4
5

6
7

export type PatchPage = {
  repoName: string,
  branchName: string,
⁣
  commits: Array<ReturnType<Repository['commits']['get']>>,
  pageNumber: number,
}
After
2
3
4
5
6
7
8

export type PatchPage = {
  repoName: string,
  relName: string,
  type: "branch" | "tag",
  commits: Array<ReturnType<Repository['commits']['get']>>,
  pageNumber: number,
}
src/paginatedPatches.ts:21
Before
20
21
22
23

24
25
26
27
28




29
30
31
32
33

34
35
    const index = paginatedPatches.findIndex((page) => {
      return (
        page.repoName === patch.repoName
        && page.branchName == patch.branchName
⁣
        && page.commits.length <= patchesPerPage
      )
    })

    if (index === -1) {
⁣
⁣
⁣
⁣
      const pageNumber = paginatedPatches.filter(page => (page.repoName === patch.repoName && page.branchName === patch.branchName)).length + 1
      paginatedPatches.push({
        repoName: patch.repoName,
        branchName: patch.branchName,
        commits: [patch.commit],
⁣
        // current page number is one more than "how many items in paginatedPatches already
        // have repoName as their repo name.
        pageNumber,
After
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    const index = paginatedPatches.findIndex((page) => {
      return (
        page.repoName === patch.repoName
        && page.relName == patch.relName
        && page.type == patch.type
        && page.commits.length <= patchesPerPage
      )
    })

    if (index === -1) {
      const pageNumber = paginatedPatches.filter(page => (
        page.repoName === patch.repoName
        && page.relName === patch.relName
        && page.type === patch.type
      )).length + 1
      paginatedPatches.push({
        repoName: patch.repoName,
        relName: patch.relName,
        commits: [patch.commit],
        type: patch.type,
        // current page number is one more than "how many items in paginatedPatches already
        // have repoName as their repo name.
        pageNumber,
src/repos.ts:162
Before
161
162
163
164
165
166
      const branchHead = branchHeadRes.stdout.split(" ")[0]
      const result = {
        name: branch.name,
        head: branchHead,
        fileList: await getFileList(branch.name, repoLocation)
      }
      if (branch.description) { result['description'] = branch.description }
After
161
162
163
164
165
166
      const branchHead = branchHeadRes.stdout.split(" ")[0]
      const result = {
        name: branch.name,
        sha: branchHead,
        fileList: await getFileList(branch.name, repoLocation)
      }
      if (branch.description) { result['description'] = branch.description }
src/repos.ts:190
Before
189
190
191
192
193
194
195
196
197
198
199
200
201
      const compareToBranch = branches.find((test) => test.name === compareTo)

      const compareToBranchCommits = new Set<string>()
      let currentCommit = commits.get(compareToBranch.head)
      while (currentCommit !== undefined) {
        compareToBranchCommits.add(currentCommit.hash)
        currentCommit = commits.get(currentCommit.parent)
      }

      const thisBranchCommits = new Set<string>()
      currentCommit = commits.get(branch.head)
      while (currentCommit !== undefined) {
        thisBranchCommits.add(currentCommit.hash)
        currentCommit = commits.get(currentCommit.parent)
After
189
190
191
192
193
194
195
196
197
198
199
200
201
      const compareToBranch = branches.find((test) => test.name === compareTo)

      const compareToBranchCommits = new Set<string>()
      let currentCommit = commits.get(compareToBranch.sha)
      while (currentCommit !== undefined) {
        compareToBranchCommits.add(currentCommit.hash)
        currentCommit = commits.get(currentCommit.parent)
      }

      const thisBranchCommits = new Set<string>()
      currentCommit = commits.get(branch.sha)
      while (currentCommit !== undefined) {
        thisBranchCommits.add(currentCommit.hash)
        currentCommit = commits.get(currentCommit.parent)