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