commits.mjs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import _ from 'lodash';
  2. export { rawCommitsToMarkdown };
  3. const commitScopesToHumanReadable = {
  4. build: 'Build system',
  5. chore: 'Chores',
  6. ci: 'Continuous integration',
  7. docs: 'Documentation',
  8. feat: 'Features',
  9. fix: 'Bug fixes',
  10. infra: 'Infrastucture',
  11. perf: 'Performance',
  12. refactor: 'Refactoring',
  13. test: 'Tests',
  14. };
  15. const commitTypesOrder = ['feat', 'fix', 'perf', 'refactor', 'test', 'build', 'ci', 'chore', 'other'];
  16. const getCommitTypeSortIndex = (type) =>
  17. commitTypesOrder.includes(type) ? commitTypesOrder.indexOf(type) : commitTypesOrder.length;
  18. function parseCommitLine(commit) {
  19. const [sha, ...splittedRawMessage] = commit.trim().split(' ');
  20. const rawMessage = splittedRawMessage.join(' ');
  21. const { type, scope, subject } = /^(?<type>.*?)(\((?<scope>.*)\))?: ?(?<subject>.+)$/.exec(rawMessage)?.groups ?? {};
  22. return {
  23. sha: sha.slice(0, 7),
  24. type: type ?? 'other',
  25. scope,
  26. subject: subject ?? rawMessage,
  27. };
  28. }
  29. function commitSectionsToMarkdown({ type, commits }) {
  30. return [
  31. `### ${commitScopesToHumanReadable[type] ?? _.capitalize(type)}`,
  32. ...commits.map(({ sha, scope, subject }) => ['-', scope ? `**${scope}**:` : '', subject, `(${sha})`].join(' ')),
  33. ].join('\n');
  34. }
  35. function rawCommitsToMarkdown({ rawCommits }) {
  36. return _.chain(rawCommits)
  37. .trim()
  38. .split('\n')
  39. .map(parseCommitLine)
  40. .groupBy('type')
  41. .map((commits, type) => ({ type, commits }))
  42. .sortBy(({ type }) => getCommitTypeSortIndex(type))
  43. .map(commitSectionsToMarkdown)
  44. .join('\n\n')
  45. .value();
  46. }