conventional-changelog 0.0.7 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -10
- package/index.js +1 -1
- package/lib/git.js +10 -9
- package/lib/writer.js +31 -11
- package/package.json +4 -4
- package/test/git.spec.js +49 -23
- package/test/writer.spec.js +5 -3
package/README.md
CHANGED
|
@@ -5,17 +5,23 @@ conventional-changelog
|
|
|
5
5
|
$ npm install conventional-changelog
|
|
6
6
|
```
|
|
7
7
|
|
|
8
|
-
Generate a changelog from git metadata, using
|
|
8
|
+
Generate a changelog from git metadata, using the AngularJS commit conventions.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
- [Synopsis of Conventions in CONVENTIONS.md](https://github.com/ajoslin/conventional-changelog/blob/master/CONVENTIONS.md)
|
|
11
|
+
- [Full Convention Spec on Google Docs](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/)
|
|
11
12
|
|
|
12
|
-
Adapted from code originally written by @vojtajina
|
|
13
|
+
Adapted from code originally written by @vojtajina and @btford in [grunt-conventional-changelog](https://github.com/btford/grunt-conventional-changelog).
|
|
13
14
|
|
|
14
15
|
## Example output
|
|
16
|
+
|
|
15
17
|
- https://github.com/ajoslin/conventional-changelog/blob/master/CHANGELOG.md
|
|
16
18
|
- https://github.com/karma-runner/karma/blob/master/CHANGELOG.md
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
## Roadmap
|
|
21
|
+
|
|
22
|
+
- Make it return a stream
|
|
23
|
+
- Add a proper command line interface
|
|
24
|
+
- Add configurable subjects & sections
|
|
19
25
|
|
|
20
26
|
## Documentation
|
|
21
27
|
|
|
@@ -38,25 +44,34 @@ By default, calls the callback with a string containing a changelog from the pre
|
|
|
38
44
|
|
|
39
45
|
`options` is the first parameter, an object. The following fields are available:
|
|
40
46
|
|
|
47
|
+
##### The Most Important Options
|
|
48
|
+
|
|
41
49
|
* `version` `{string}` - The version to be written to the changelog. For example, `{version: require('./package.json').version}`
|
|
42
50
|
|
|
43
|
-
* `
|
|
51
|
+
* `subtitle` `{string}` - A string to display after the version title in the changelog. For example, it will show '## 1.0.0 "Super Version"' if codename '"Super Version"' is given. By default, it's blank.
|
|
44
52
|
|
|
45
53
|
* `repository` `{string}` - If this is provided, allows issues and commit hashes to be linked to the actual commit. Usually used with github repositories. For example, `{repository: 'http://github.com/joyent/node'}`
|
|
46
54
|
|
|
47
|
-
* `commitLink` `{function(commitHash)}` - If repository is provided, this function will be used to link to commits. By default, returns a github commit link based on options.repository: `opts.repository + '/commit/' + hash`
|
|
48
|
-
|
|
49
|
-
* `issueLink` `{function(issueId)}` - If repository is provided, this function will be used to link to issues. By default, returns a github issue link based on options.repository: `opts.repository + '/issues/' + id`
|
|
50
|
-
|
|
51
55
|
* `from` `{string}` - Which commit the changelog should start at. By default, uses previous tag, or if no previous tag the first commit.
|
|
52
56
|
|
|
53
57
|
* `to` `{string}` - Which commit the changelog should end at. By default, uses HEAD.
|
|
54
58
|
|
|
55
|
-
* `file` `{string}` - Which file to read the current changelog from and prepend the new changelog's contents to. By default, uses `'CHANGELOG.md'
|
|
59
|
+
* `file` `{string}` - Which file to read the current changelog from and prepend the new changelog's contents to. By default, uses `'CHANGELOG.md'`
|
|
60
|
+
|
|
61
|
+
##### The "I really want to get crazy" Options
|
|
62
|
+
|
|
63
|
+
* `versionText` `{function(version, subtitle)}` - What to use for the title of a major version in the changelog. Defaults to `'## ' + version + ' ' + subtitle`.
|
|
64
|
+
|
|
65
|
+
* `patchVersionText` `{function(version, subtitle)}` - What to use for the title of a patch version in the changelog. Defaults to `'### ' + version + ' ' + subtitle`.
|
|
66
|
+
|
|
67
|
+
* `commitLink` `{function(commitHash)}` - If repository is provided, this function will be used to link to commits. By default, returns a github commit link based on options.repository: `opts.repository + '/commit/' + hash`
|
|
68
|
+
|
|
69
|
+
* `issueLink` `{function(issueId)}` - If repository is provided, this function will be used to link to issues. By default, returns a github issue link based on options.repository: `opts.repository + '/issues/' + id`
|
|
56
70
|
|
|
57
71
|
* `log` `{function()}` - What logging function to use. For example, `{log: grunt.log.ok}`. By default, uses `console.log`.
|
|
58
72
|
|
|
59
73
|
* `warn` `{function()}` - What warn function to use. For example, `{warn: grunt.log.writeln}`. By default, uses `console.warn`.
|
|
60
74
|
|
|
61
75
|
## License
|
|
76
|
+
|
|
62
77
|
BSD
|
package/index.js
CHANGED
package/lib/git.js
CHANGED
|
@@ -49,7 +49,7 @@ function getCommits(options, done) {
|
|
|
49
49
|
cmd,
|
|
50
50
|
options.grep,
|
|
51
51
|
options.format,
|
|
52
|
-
options.from ? options.from+'..'+options.to : ''
|
|
52
|
+
options.from ? '"' + options.from + '..' + options.to + '"' : ''
|
|
53
53
|
);
|
|
54
54
|
|
|
55
55
|
return es.child(cp.exec(cmd))
|
|
@@ -62,7 +62,7 @@ function getCommits(options, done) {
|
|
|
62
62
|
.pipe(es.writeArray(done));
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
var COMMIT_PATTERN = /^(\w*)(\(([\w\$\.\-\*]*)\))?\: (.*)$/;
|
|
65
|
+
var COMMIT_PATTERN = /^(\w*)(\(([\w\$\.\-\* ]*)\))?\: (.*)$/;
|
|
66
66
|
var MAX_SUBJECT_LENGTH = 80;
|
|
67
67
|
function parseRawCommit(raw, options) {
|
|
68
68
|
if (!raw) {
|
|
@@ -77,24 +77,25 @@ function parseRawCommit(raw, options) {
|
|
|
77
77
|
msg.closes = [];
|
|
78
78
|
msg.breaks = [];
|
|
79
79
|
|
|
80
|
-
msg.subject = msg.subject.replace(/\s*(?:Closes|Fixes)\s#(\d+)
|
|
80
|
+
msg.subject = msg.subject.replace(/\s*(?:Closes|Fixes|Resolves)\s#(\d+)/ig, function(_, i) {
|
|
81
81
|
msg.closes.push(parseInt(i, 10));
|
|
82
82
|
return '';
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
lines.forEach(function(line) {
|
|
86
|
-
match = line.match(/(?:Closes|Fixes)\s((?:#\d+(?:\,\s)?)+)/);
|
|
86
|
+
match = line.match(/(?:Closes|Fixes|Resolves)\s((?:#\d+(?:\,\s)?)+)/ig);
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
match && match.forEach(function(m) {
|
|
89
|
+
m && m.split(',').forEach(function(i) {
|
|
90
|
+
var issue = i.match(/\d+/);
|
|
91
|
+
issue && msg.closes.push(parseInt(issue[0], 10));
|
|
91
92
|
});
|
|
92
|
-
}
|
|
93
|
+
});
|
|
93
94
|
});
|
|
94
95
|
|
|
95
96
|
match = raw.match(/BREAKING CHANGE:\s([\s\S]*)/);
|
|
96
97
|
if (match) {
|
|
97
|
-
msg.breaks.push(match[1]);
|
|
98
|
+
msg.breaks.push(match[1] + '\n');
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
msg.body = lines.join('\n');
|
package/lib/writer.js
CHANGED
|
@@ -2,6 +2,8 @@ var es = require('event-stream');
|
|
|
2
2
|
var util = require('util');
|
|
3
3
|
var extend = require('lodash.assign');
|
|
4
4
|
|
|
5
|
+
var VERSION = '## %s%s';
|
|
6
|
+
var PATCH_VERSION = '### %s%s';
|
|
5
7
|
var LINK_ISSUE = '[#%s](%s/issues/%s)';
|
|
6
8
|
var ISSUE = '(#%s)';
|
|
7
9
|
var LINK_COMMIT = '[%s](%s/commit/%s)';
|
|
@@ -12,6 +14,14 @@ module.exports = {
|
|
|
12
14
|
Writer: Writer
|
|
13
15
|
};
|
|
14
16
|
|
|
17
|
+
function getVersion (version, subtitle) {
|
|
18
|
+
subtitle = subtitle ? ' ' + subtitle : '';
|
|
19
|
+
return util.format(VERSION, version, subtitle);
|
|
20
|
+
}
|
|
21
|
+
function getPatchVersion (version, subtitle) {
|
|
22
|
+
subtitle = subtitle ? ' ' + subtitle : '';
|
|
23
|
+
return util.format(PATCH_VERSION, version, subtitle);
|
|
24
|
+
}
|
|
15
25
|
function getIssueLink(repository, issue) {
|
|
16
26
|
return repository ?
|
|
17
27
|
util.format(LINK_ISSUE, issue, repository, issue) :
|
|
@@ -25,10 +35,6 @@ function getCommitLink(repository, hash) {
|
|
|
25
35
|
}
|
|
26
36
|
|
|
27
37
|
function writeLog(commits, options, done) {
|
|
28
|
-
options = extend({
|
|
29
|
-
issueLink: getIssueLink.bind(null, options.repository),
|
|
30
|
-
commitLink: getCommitLink.bind(null, options.repository)
|
|
31
|
-
}, options || {});
|
|
32
38
|
|
|
33
39
|
var log = '';
|
|
34
40
|
var stream = es.through(function(data) {
|
|
@@ -71,15 +77,29 @@ function writeLog(commits, options, done) {
|
|
|
71
77
|
writer.end();
|
|
72
78
|
}
|
|
73
79
|
|
|
74
|
-
var
|
|
75
|
-
var
|
|
80
|
+
var LINK_HEADER_TPL = '%s (%s)\n\n';
|
|
81
|
+
var PLAIN_HEADER_TPL = '<a name="%s"></a>\n%s (%s)\n\n';
|
|
76
82
|
var EMPTY_COMPONENT = '$$';
|
|
77
|
-
function Writer(stream, options) {
|
|
78
83
|
|
|
84
|
+
function Writer(stream, options) {
|
|
85
|
+
options = extend({
|
|
86
|
+
versionText: getVersion,
|
|
87
|
+
patchVersionText: getPatchVersion,
|
|
88
|
+
issueLink: getIssueLink.bind(null, options.repository),
|
|
89
|
+
commitLink: getCommitLink.bind(null, options.repository)
|
|
90
|
+
}, options || {});
|
|
91
|
+
|
|
79
92
|
this.header = function(version) {
|
|
80
|
-
var
|
|
81
|
-
var
|
|
82
|
-
|
|
93
|
+
var subtitle = options.subtitle || '';
|
|
94
|
+
var versionText = version.split('.')[2] === '0' ?
|
|
95
|
+
options.versionText(version, subtitle) :
|
|
96
|
+
options.patchVersionText(version, subtitle);
|
|
97
|
+
|
|
98
|
+
if (options.repository) {
|
|
99
|
+
stream.write(util.format(LINK_HEADER_TPL, versionText, currentDate()));
|
|
100
|
+
} else {
|
|
101
|
+
stream.write(util.format(PLAIN_HEADER_TPL, version, versionText, currentDate()));
|
|
102
|
+
}
|
|
83
103
|
};
|
|
84
104
|
|
|
85
105
|
this.section = function(title, section) {
|
|
@@ -122,7 +142,7 @@ function Writer(stream, options) {
|
|
|
122
142
|
this.end = function() {
|
|
123
143
|
stream.end();
|
|
124
144
|
};
|
|
125
|
-
}
|
|
145
|
+
}
|
|
126
146
|
|
|
127
147
|
function currentDate() {
|
|
128
148
|
var now = new Date();
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conventional-changelog",
|
|
3
|
-
"codename": "
|
|
4
|
-
"version": "0.0.
|
|
3
|
+
"codename": "reorder",
|
|
4
|
+
"version": "0.0.11",
|
|
5
5
|
"description": "Generate a markdown changelog from git commit metadata",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"test": "mocha test/*.js index.js lib/*.js"
|
|
8
|
+
"test": "mocha test/*.js index.js lib/*.js --no-colors"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"name": "Vojta Jína"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
|
-
"name": "
|
|
31
|
+
"name": "Andrew Joslin"
|
|
32
32
|
}
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
package/test/git.spec.js
CHANGED
|
@@ -36,46 +36,72 @@ describe('git', function() {
|
|
|
36
36
|
'bla bla bla\n\n' +
|
|
37
37
|
'BREAKING CHANGE: some breaking change\n'
|
|
38
38
|
);
|
|
39
|
-
expect(msg.breaks).to.deep.equal(['some breaking change\n']);
|
|
39
|
+
expect(msg.breaks).to.deep.equal(['some breaking change\n\n']);
|
|
40
40
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
['Closes', 'Fixes', 'Resolves'].forEach(function(closeWord) {
|
|
42
|
+
it('should parse ' + closeWord + ' in the subject (and remove it)', function() {
|
|
43
|
+
var msg = git.parseRawCommit(
|
|
44
|
+
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
|
|
45
|
+
'feat(xxx): Whatever ' + closeWord + ' #24\n' +
|
|
46
|
+
'bla bla bla\n\n' +
|
|
47
|
+
'What not ?\n'
|
|
48
|
+
);
|
|
49
|
+
expect(msg.closes).to.deep.equal([24]);
|
|
50
|
+
expect(msg.subject).to.equal('Whatever');
|
|
51
|
+
});
|
|
52
|
+
it('should work with lowercase ' + closeWord + ' in the subject', function() {
|
|
53
|
+
var msg = git.parseRawCommit(
|
|
54
|
+
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
|
|
55
|
+
'feat(xxx): Whatever ' + closeWord.toLowerCase() + ' #24\n' +
|
|
56
|
+
'bla bla bla\n\n' +
|
|
57
|
+
'What not ?\n'
|
|
58
|
+
);
|
|
59
|
+
expect(msg.closes).to.deep.equal([24]);
|
|
60
|
+
expect(msg.subject).to.equal('Whatever');
|
|
61
|
+
});
|
|
62
|
+
it('should parse multiple comma-separated issues closed with ' + closeWord + ' #1, #2', function() {
|
|
63
|
+
var msg = git.parseRawCommit(
|
|
64
|
+
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
|
|
65
|
+
'fix(yyy): Very cool commit\n' +
|
|
66
|
+
'bla bla bla\n\n' +
|
|
67
|
+
closeWord + ' #1, #22, #33\n' +
|
|
68
|
+
'What not ?\n'
|
|
69
|
+
);
|
|
70
|
+
expect(msg.closes).to.deep.equal([1, 22, 33]);
|
|
71
|
+
expect(msg.subject).to.equal('Very cool commit');
|
|
72
|
+
});
|
|
50
73
|
});
|
|
51
|
-
it('should parse
|
|
74
|
+
it('should parse multiple period-separated issues closed with all closed words', function() {
|
|
52
75
|
var msg = git.parseRawCommit(
|
|
53
76
|
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
|
|
54
|
-
'
|
|
55
|
-
'bla bla bla\n\n' +
|
|
77
|
+
'fix(zzz): Very cool commit\n' +
|
|
78
|
+
'bla bla bla\n\n' +
|
|
79
|
+
'Closes #2, #3. Resolves #4. Fixes #5. Fixes #6.\n' +
|
|
56
80
|
'What not ?\n'
|
|
57
81
|
);
|
|
58
|
-
expect(msg.closes).to.deep.equal([
|
|
59
|
-
expect(msg.subject).to.equal('
|
|
82
|
+
expect(msg.closes).to.deep.equal([2,3,4,5,6]);
|
|
83
|
+
expect(msg.subject).to.equal('Very cool commit');
|
|
60
84
|
});
|
|
61
|
-
it('should parse
|
|
85
|
+
it('should parse a msg without scope', function() {
|
|
62
86
|
var msg = git.parseRawCommit(
|
|
63
87
|
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
|
|
64
|
-
'
|
|
88
|
+
'chore: some chore\n' +
|
|
65
89
|
'bla bla bla\n\n' +
|
|
66
|
-
'
|
|
67
|
-
'What not ?\n'
|
|
90
|
+
'BREAKING CHANGE: some breaking change\n'
|
|
68
91
|
);
|
|
69
|
-
expect(msg.
|
|
92
|
+
expect(msg.type).to.equal('chore');
|
|
93
|
+
expect(msg.subject).to.equal('some chore');
|
|
70
94
|
});
|
|
71
|
-
it('should parse a
|
|
95
|
+
it('should parse a scope with spaces', function() {
|
|
72
96
|
var msg = git.parseRawCommit(
|
|
73
97
|
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
|
|
74
|
-
'chore: some chore
|
|
75
|
-
'bla bla bla\n\n' +
|
|
98
|
+
'chore(scope with spaces): some chore\n' +
|
|
99
|
+
'bla bla bla\n\n' +
|
|
76
100
|
'BREAKING CHANGE: some breaking change\n'
|
|
77
101
|
);
|
|
78
102
|
expect(msg.type).to.equal('chore');
|
|
103
|
+
expect(msg.subject).to.equal('some chore');
|
|
104
|
+
expect(msg.component).to.equal('scope with spaces');
|
|
79
105
|
});
|
|
80
106
|
});
|
|
81
107
|
});
|
package/test/writer.spec.js
CHANGED
|
@@ -18,6 +18,8 @@ describe("Writer", function() {
|
|
|
18
18
|
log = '';
|
|
19
19
|
var stream = es.through(concat, concat.bind(null,'END'));
|
|
20
20
|
return new writer.Writer(stream, {
|
|
21
|
+
subtitle: 'subby',
|
|
22
|
+
repository: 'github.com/user/repo',
|
|
21
23
|
issueLink: function(id) {
|
|
22
24
|
return id;
|
|
23
25
|
},
|
|
@@ -31,12 +33,12 @@ describe("Writer", function() {
|
|
|
31
33
|
it('minor version', function() {
|
|
32
34
|
var writer = setup();
|
|
33
35
|
writer.header('0.1.0');
|
|
34
|
-
expect(log.
|
|
36
|
+
expect(log).to.contain('## 0.1.0 subby');
|
|
35
37
|
});
|
|
36
38
|
it('patch version', function() {
|
|
37
39
|
var writer = setup();
|
|
38
|
-
writer.header('0.0.
|
|
39
|
-
expect(log.
|
|
40
|
+
writer.header('0.0.3');
|
|
41
|
+
expect(log).to.contain('### 0.0.3 subby');
|
|
40
42
|
});
|
|
41
43
|
});
|
|
42
44
|
|