1 | const { EOL } = require('os')
|
2 | const fs = require('fs')
|
3 | const { Plugin } = require('release-it')
|
4 | const conventionalChangelog = require('conventional-changelog')
|
5 | const concat = require('concat-stream')
|
6 | const prependFile = require('prepend-file')
|
7 |
|
8 | class ConventionalChangelog extends Plugin {
|
9 | getInitialOptions(options, namespace) {
|
10 | options[namespace].tagName = options.git.tagName
|
11 | return options[namespace]
|
12 | }
|
13 |
|
14 | async bump(version) {
|
15 | this.setContext({ version })
|
16 | const { previousTag, currentTag } = await this.getConventionalConfig()
|
17 | this.setContext({ previousTag, currentTag })
|
18 | const changelog = await this.generateChangelog()
|
19 | this.setContext({ changelog })
|
20 | }
|
21 |
|
22 | async getConventionalConfig() {
|
23 | const version = this.getContext('version')
|
24 |
|
25 | const previousTag = this.config.getContext('latestTag')
|
26 | const tagTemplate =
|
27 | this.options.tagName || ((previousTag || '').match(/^v/) ? 'v${version}' : '${version}')
|
28 | const currentTag = tagTemplate.replace('${version}', version)
|
29 |
|
30 | return { version, previousTag, currentTag }
|
31 | }
|
32 |
|
33 | getChangelogStream(options = {}) {
|
34 | const { version, previousTag, currentTag } = this.getContext()
|
35 | return conventionalChangelog(
|
36 | Object.assign(options, this.options),
|
37 | { version, previousTag, currentTag },
|
38 | {
|
39 | debug: this.config.isDebug ? this.debug : null,
|
40 | }
|
41 | )
|
42 | }
|
43 |
|
44 | generateChangelog(options) {
|
45 | return new Promise((resolve, reject) => {
|
46 | const resolver = result => resolve(result.toString().trim())
|
47 | const changelogStream = this.getChangelogStream(options)
|
48 | changelogStream.pipe(concat(resolver))
|
49 | changelogStream.on('error', reject)
|
50 | })
|
51 | }
|
52 |
|
53 | async writeChangelog() {
|
54 | const { infile } = this.options
|
55 | let { changelog } = this.getContext()
|
56 |
|
57 | let hasInfile = false
|
58 | try {
|
59 | fs.accessSync(infile)
|
60 | hasInfile = true
|
61 | } catch (err) {
|
62 | this.debug(err)
|
63 | }
|
64 |
|
65 | if (!hasInfile) {
|
66 | changelog = await this.generateChangelog({ releaseCount: 0 })
|
67 | this.debug({ changelog })
|
68 | }
|
69 |
|
70 | await prependFile(infile, changelog + EOL + EOL)
|
71 |
|
72 | if (!hasInfile) {
|
73 | await this.exec(`git add ${infile}`)
|
74 | }
|
75 | }
|
76 |
|
77 | async beforeRelease() {
|
78 | const { infile } = this.options
|
79 | const { isDryRun } = this.config
|
80 |
|
81 | this.log.exec(`Writing changelog to ${infile}`, isDryRun)
|
82 |
|
83 | if (infile && !isDryRun) {
|
84 | await this.writeChangelog()
|
85 | }
|
86 | }
|
87 | }
|
88 |
|
89 | module.exports = ConventionalChangelog
|