changelog.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. 'use strict'
  2. /*
  3. Usage:
  4. node scripts/changelog.js [comittish]
  5. Generates changelog entries in our format as best as its able based on
  6. commits starting at comittish, or if that's not passed, latest.
  7. Ordinarily this is run via the gen-changelog shell script, which appends
  8. the result to the changelog.
  9. */
  10. const execSync = require('child_process').execSync
  11. const branch = process.argv[2] || 'origin/latest'
  12. const log = execSync(`git log --reverse --pretty='format:%h %H%d %s (%aN)%n%b%n---%n' ${branch}...`).toString().split(/\n/)
  13. main()
  14. function shortname (url) {
  15. let matched = url.match(/https:\/\/github\.com\/([^/]+\/[^/]+)\/(?:pull|issues)\/(\d+)/) ||
  16. url.match(/https:\/\/(npm\.community)\/t\/(?:[^/]+\/)(\d+)/)
  17. if (!matched) return false
  18. let repo = matched[1]
  19. let id = matched[2]
  20. if (repo !== 'npm/cli') {
  21. return `${repo}#${id}`
  22. } else {
  23. return `#${id}`
  24. }
  25. }
  26. function printCommit (c) {
  27. console.log(`* [\`${c.shortid}\`](https://github.com/npm/cli/commit/${c.fullid})`)
  28. if (c.fixes) {
  29. let label = shortname(c.fixes)
  30. if (label) {
  31. console.log(` [${label}](${c.fixes})`)
  32. } else {
  33. console.log(` [npm.community#${c.fixes}](https://npm.community/t/${c.fixes})`)
  34. }
  35. } else if (c.prurl) {
  36. let label = shortname(c.prurl)
  37. if (label) {
  38. console.log(` [${label}](${c.prurl})`)
  39. } else {
  40. console.log(` [#](${c.prurl})`)
  41. }
  42. }
  43. let msg = c.message
  44. .replace(/^\s+/mg, '')
  45. .replace(/^[-a-z]+: /, '')
  46. .replace(/^/mg, ' ')
  47. .replace(/\n$/, '')
  48. // backtickify package@version
  49. .replace(/^(\s*[^@\s]+@\d+[.]\d+[.]\d+)(\s*\S)/g, '$1:$2')
  50. .replace(/\b([^@\s]+@\d+[.]\d+[.]\d+)\b/g, '`$1`')
  51. // linkify commitids
  52. .replace(/\b([a-f0-9]{7,8})\b/g, '[`$1`](https://github.com/npm/cli/commit/$1)')
  53. .replace(/\b#(\d+)\b/g, '[#$1](https://npm.community/t/$1)')
  54. console.log(msg)
  55. if (c.credit) {
  56. c.credit.forEach(function (credit) {
  57. console.log(` ([@${credit}](https://github.com/${credit}))`)
  58. })
  59. } else {
  60. console.log(` ([@${c.author}](https://github.com/${c.author}))`)
  61. }
  62. }
  63. function main () {
  64. let commit
  65. log.forEach(function (line) {
  66. line = line.replace(/\r/g, '')
  67. let m
  68. /* eslint no-cond-assign:0 */
  69. if (/^---$/.test(line)) {
  70. printCommit(commit)
  71. } else if (m = line.match(/^([a-f0-9]{7,10}) ([a-f0-9]+) (?:[(]([^)]+)[)] )?(.*?) [(](.*?)[)]/)) {
  72. commit = {
  73. shortid: m[1],
  74. fullid: m[2],
  75. branch: m[3],
  76. message: m[4],
  77. author: m[5],
  78. prurl: null,
  79. fixes: null,
  80. credit: null
  81. }
  82. } else if (m = line.match(/^PR-URL: (.*)/)) {
  83. commit.prurl = m[1]
  84. } else if (m = line.match(/^Credit: @(.*)/)) {
  85. if (!commit.credit) commit.credit = []
  86. commit.credit.push(m[1])
  87. } else if (m = line.match(/^Fixes: #?(.*)/)) {
  88. commit.fixes = m[1]
  89. } else if (m = line.match(/^Reviewed-By: @(.*)/)) {
  90. commit.reviewed = m[1]
  91. } else if (/\S/.test(line)) {
  92. commit.message += `\n${line}`
  93. }
  94. })
  95. }