Parse raw conventional commits
Adapted from code originally written by @ajoslin in conventional-changelog.
Conventional Commit Message Format
Each input commit message consists of a hash (optional), a header, a body (optional) and a footer (optional).
<hash>
<header>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
The header has a special format that includes a type, a scope (optional) and a subject
<type>(<scope>): <subject>
The footer should contain any information about Important Notes (optional) and is also the place to reference GitHub issues that this commit Closes (optional).
<important note>
<BLANK LINE>
<closes>
More details
Install
$ npm install --save conventional-commits-parser
Usage
var conventionalCommitsParser = require('conventional-commits-parser');
var through = require('through2');
var rawCommits = [
'9b1aff905b638aa274a5fc8f88662df446d374bd\n' +
'feat(scope): broadcast $destroy event on scope destruction\n' +
'Closes #1',
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
'feat(ng-list): Allow custom separator\n' +
'bla bla bla\n\n' +
'BREAKING CHANGE: some breaking change\n'
];
var stream = through();
stream.write(rawCommits[0]);
stream.write(rawCommits[1]);
stream
.pipe(conventionalCommitsParser())
.pipe(through.obj(function(chunk, enc, cb) {
console.log(chunk);
cb();
}));
API
conventionalCommitsParser([options])
Returns an object stream. If there is any malformed commits it will be gracefully ignored (an empty data will be emitted so down stream can notice).
options
Type: object
maxSubjectLength
Type: number
Default: 80
The maximum subject length.
Type: regex
or string
Default: /^(\w*)(?:\(([\w\$\.\-\* ]*)\))?\: (.*)$/
Used to match header pattern. The first capturing group captures type, second captures scope and third captures subject. If it's a string
it will be converted to a regex
.
closeKeywords
Type: array
or string
Default:
[ 'close', 'closes', 'closed', 'fix', 'fixes', 'fixed', 'resolve', 'resolves', 'resolved' ]
This value is case insensitive. If it's a string
it will be converted to an array
separated by a comma.
Keywords that used to close issues.
noteKeywords
Type: array
or string
Default: ['BREAKING CHANGE']
Keywords for important notes. If it's a string
it will be converted to an array
separated by a comma.
warn
Type: function
or boolean
Default: function() {}
What warn function to use. For example, console.warn.bind(console)
or grunt.log.writeln
. By default, it's a noop. If it is true
, it will error if commit cannot be parsed (strict).
CLI
You can use cli to practice writing commit messages or test from a file.
$ npm install --global conventional-commits-parser
If you run conventional-commits-parser
without any arguments
$ conventional-commits-parser
You will enter an interactive shell. To show your parsed result enter "return" three times (or enter your specified separator).
> fix(title): a title is fixed
result: {"hash":null,"header":"fix(title): a title is fixed","body":"","footer":"","notes":{},"closes":[],"type":"fix","scope":"title","subject":"a title is fixed"}
You can also use cli to test commits from a file.
If you have log.txt
9b1aff905b638aa274a5fc8f88662df446d374bd
feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the ngMessage directive to represent the name of the error.
BREAKING CHANGE: The `ngMessagesInclude` attribute is now its own directive and that must be placed as a **child** element within the element with the ngMessages directive.
Closes #10036
Closes #9338
And you run
$ conventional-commits-parser log.txt
$ cat log.txt | conventional-commits-parser
An array of json will be printed to stdout.
[
{"hash":"9b1aff905b638aa274a5fc8f88662df446d374bd","header":"feat(ngMessages): provide support for dynamic message resolution","body":"Prior to this fix it was impossible to apply a binding to a the ngMessage directive to represent the name of the error.","footer":"BREAKING CHANGE: The `ngMessagesInclude` attribute is now its own directive and that must be placed as a **child** element within the element with the ngMessages directive.\nCloses #10036\nCloses #9338","notes":{"BREAKING CHANGE":"The `ngMessagesInclude` attribute is now its own directive and that must be placed as a **child** element within the element with the ngMessages directive."},"closes":[10036,9338],"type":"feat","scope":"ngMessages","subject":"provide support for dynamic message resolution"}
]
Commits should be split by at least three newlines (\n\n\n
) or you can specify a separator as the second argument.
Eg: in log2.txt
2d0eda10e43f6b079b531c507282fad082ea0762
docs(ngMessageExp): split ngMessage docs up to show its alias more clearly
===
4374f892c6fa4af6ba1f2ed47c5f888fdb5fadc5
fix($animate): applyStyles from options on leave
Closes #10068
And you run
$ conventional-commits-parser log2.txt '==='
[
{"hash":"2d0eda10e43f6b079b531c507282fad082ea0762","header":"docs(ngMessageExp): split ngMessage docs up to show its alias more clearly","body":"","footer":"","notes":{},"closes":[],"type":"docs","scope":"ngMessageExp","subject":"split ngMessage docs up to show its alias more clearly"}
,
{"hash":"4374f892c6fa4af6ba1f2ed47c5f888fdb5fadc5","header":"fix($animate): applyStyles from options on leave","body":"","footer":"Closes #10068","notes":{},"closes":[10068],"type":"fix","scope":"$animate","subject":"applyStyles from options on leave"}
]
Will be printed out.
You can specify one or more files. The output array will be in order of the input file paths. If you specify more than one separator, the last one will be used.
License
MIT © Steve Mao