forked from release-it/conventional-changelog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
121 lines (103 loc) · 3.81 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
const { EOL } = require('os');
const fs = require('fs');
const { Plugin } = require('release-it');
const conventionalRecommendedBump = require('conventional-recommended-bump');
const conventionalChangelog = require('conventional-changelog');
const semver = require('semver');
const concat = require('concat-stream');
const prependFile = require('prepend-file');
class ConventionalChangelog extends Plugin {
static disablePlugin() {
return 'version';
}
getInitialOptions(options, namespace) {
options[namespace].tagName = options.git.tagName;
return options[namespace];
}
async getChangelog(latestVersion) {
const { version, previousTag, currentTag } = await this.getConventionalConfig(latestVersion);
this.setContext({ version, previousTag, currentTag });
return this.generateChangelog();
}
async getConventionalConfig(latestVersion) {
const { increment, isPreRelease, preReleaseId } = this.config.getContext('version');
const version = await this.getIncrementedVersion({ increment, latestVersion, isPreRelease, preReleaseId });
this.setContext({ version });
const previousTag = this.config.getContext('latestTag');
const tagTemplate = this.options.tagName || ((previousTag || '').match(/^v/) ? 'v${version}' : '${version}');
const currentTag = tagTemplate.replace('${version}', version);
return { version, previousTag, currentTag };
}
getIncrementedVersion({ increment, latestVersion, isPreRelease, preReleaseId }) {
const { version } = this.getContext();
if (version) return version;
this.debug({ increment, latestVersion, isPreRelease, preReleaseId });
return new Promise((resolve, reject) =>
conventionalRecommendedBump(this.options, (err, result) => {
this.debug({ err, result });
if (err) return reject(err);
let { releaseType } = result;
if (increment) {
this.log.warn(`Recommended bump is "${releaseType}", but is overridden with "${increment}".`);
releaseType = increment;
}
if (increment && semver.valid(increment)) {
resolve(increment);
} else if (isPreRelease) {
const type = increment ? `pre${releaseType}` : 'prerelease';
resolve(semver.inc(latestVersion, type, preReleaseId));
} else if (releaseType) {
resolve(semver.inc(latestVersion, releaseType, preReleaseId));
} else {
resolve(null);
}
})
);
}
getChangelogStream(options = {}) {
const { version, previousTag, currentTag } = this.getContext();
return conventionalChangelog(
Object.assign(options, this.options),
{ version, previousTag, currentTag },
{
debug: this.config.isDebug ? this.debug : null
}
);
}
generateChangelog(options) {
return new Promise((resolve, reject) => {
const resolver = result => resolve(result.toString().trim());
const changelogStream = this.getChangelogStream(options);
changelogStream.pipe(concat(resolver));
changelogStream.on('error', reject);
});
}
async writeChangelog() {
const { infile } = this.options;
let { changelog } = this.config.getContext();
let hasInfile = false;
try {
fs.accessSync(infile);
hasInfile = true;
} catch (err) {
this.debug(err);
}
if (!hasInfile) {
changelog = await this.generateChangelog({ releaseCount: 0 });
this.debug({ changelog });
}
await prependFile(infile, changelog + EOL + EOL);
if (!hasInfile) {
await this.exec(`git add ${infile}`);
}
}
async beforeRelease() {
const { infile } = this.options;
const { isDryRun } = this.config;
this.log.exec(`Writing changelog to ${infile}`, isDryRun);
if (infile && !isDryRun) {
await this.writeChangelog();
}
}
}
module.exports = ConventionalChangelog;