Tucker McKnight <tmcknight@instructure.com> | Sun Jul 12 2026
Make language bar chart determined by line count Previously, was based on the number of files for each language. Is now based on the number of lines in those files. Also, hides the "other" bar if there is nothing in the "other" category. Will also show fewer bars if there are less than 5 languages. (Previously, was hard-coded to 5.)
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
currentRefType: data.flatRef.type,
})
const languageCounts = Array.from(ref.fileList.keys()).reduce((counts, currentFile) => {
const fileParts = currentFile.split(".")
const fileExtension = fileParts[fileParts.length - 1]
// todo: add more ignoreable extensions or specific files
// (like package-lock.json). Allow glob patterns?
if (fileExtension === 'gitignore') {
return counts
}
counts.set(fileExtension, (counts.get(fileExtension) + 1) || 1)
return counts
}, new Map<string, number>())
// todo: this is probably broken for repos that use fewer than 6 languages
let languagePercentages: Array<[string, number]> = []
const total = Array.from(ref.fileList.keys()).length
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
currentRefType: data.flatRef.type,
})
const languageCounts = new Map<string, number>()
const countPromises = Array.from(ref.fileList.keys()).map(async (currentFile) => {
return new Promise<void>(async (resolve) => {
const fileParts = currentFile.split(".")
const fileExtension = fileParts[fileParts.length - 1]
// todo: add more ignoreable extensions or specific files
// (like package-lock.json). Allow glob patterns?
if (fileExtension === 'gitignore') {
resolve()
}
const fileLineCount = (await repo.files(currentFile, data.currentRef.sha)).contents.split('\n').length
languageCounts.set(fileExtension, (languageCounts.get(fileExtension) + fileLineCount) || fileLineCount)
resolve()
})
})
await Promise.all(countPromises)
let languagePercentages: Array<[string, number]> = []
const total = Array.from(ref.fileList.keys()).length
44 45 46 47 48 49 50
languagePercentages.sort((a, b) => {
return b[1] - a[1]
})
const topLanguagePercentages = languagePercentages.slice(0, 5)
const otherLanguagePercent = languagePercentages.slice(6, languagePercentages.length - 6).reduce((sum, current) => {
return sum + current[1]
}, 0)
44 45 46 47 48 49 50 51 52 53
languagePercentages.sort((a, b) => {
return b[1] - a[1]
})
// Show graph for the top 5 languages, unless there are fewer than 5 total
const numOfTopLanguages = Math.min(5, languagePercentages.length)
const topLanguagePercentages = languagePercentages.slice(0, numOfTopLanguages)
const otherLanguagePercent = languagePercentages.slice(numOfTopLanguages).reduce((sum, current) => {
return sum + current[1]
}, 0)
74 75 76 77 78 79 80 81 82
m('div', {class: "language-name text-light font-monospace"}, percentTuple[0]),
m('div', {class: "language-percent", style: `flex-grow: ${percentTuple[1] / largestPercent};`})
])
}).concat([m('div', {class: 'language-col flex-grow-1 overflow-hidden'},
m('div', {class: "language-name text-light font-monospace"}, 'other'),
m('div', {class: "language-percent", style: `flex-grow: ${otherLanguagePercent / largestPercent};`})
)])),
])
]),
m('div', {class: "row align-items-center"}, [74 75 76 77 78 79 80 81 82 83 84 85 86
m('div', {class: "language-name text-light font-monospace"}, percentTuple[0]),
m('div', {class: "language-percent", style: `flex-grow: ${percentTuple[1] / largestPercent};`})
])
}).concat(
otherLanguagePercent > 0
? [m('div', {class: 'language-col flex-grow-1 overflow-hidden'},
m('div', {class: "language-name text-light font-monospace"}, 'other'),
m('div', {class: "language-percent", style: `flex-grow: ${otherLanguagePercent / largestPercent};`})
)]
: null
)),
])
]),
m('div', {class: "row align-items-center"}, [47 48 49 50 51 52 53
export type GitConfig = {
/* The absolute path to the repository.
* @example location: "/home/alice/projects/git_repo"
*/
location: string,
description?: string,
defaultBranch: string,47 48 49 50 51 52 53
export type GitConfig = {
/* The absolute path to the repository.
* @example location: "/home/alice/projects/git_repo"
*/
location: string,
description?: string,
defaultBranch: string,