master
 1import { define, plural } from '#src'
 2import { removeStopwords } from 'stopword'
 3
 4export default define({
 5  url: import.meta.url,
 6  badges: ['favorite-word'] as const,
 7  present(data, grant) {
 8    const counts: Record<string, number> = {}
 9    for (const repo of data.repos) {
10      for (const commit of repo.commits) {
11        const msg = commit.message + '\n' + commit.messageBody
12        const words = splitWithoutTooFrequentWords(msg)
13        for (const word of words) {
14          counts[word] = (counts[word] || 0) + 1
15        }
16      }
17    }
18    const pairs = Object.entries(counts)
19    pairs.sort((a, b) => b[1] - a[1])
20    if (pairs.length === 0) return
21    const topWords = pairs.slice(0, 5)
22    grant('favorite-word', `My favorite word is "${topWords[0][0]}".`).evidence(
23      `My favorite commit message words are:\n\n` +
24        topWords
25          .map(
26            (p, i) =>
27              `${i + 1}. ${p[0]} (used ${plural(p[1], 'once', '%d times')})`,
28          )
29          .join('\n'),
30    )
31  },
32})
33
34export function splitWithoutTooFrequentWords(msg: string) {
35  return removeStopwords(
36    msg
37      .toLowerCase()
38      // remove conventional commit prefixes as they would outweigh other words
39      .replace(
40        /^(breaking changes?|build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(?:\(.*?\))?!?:/gm,
41        '',
42      )
43      .split(/\s+/)
44      // ignore words not including alphanumeric chars
45      .filter((w) => /\w/.test(w)),
46  )
47}