Skip to content
This repository has been archived by the owner on Feb 5, 2018. It is now read-only.

Commit

Permalink
feat(headerParts): headerParts can be anything
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `headerParts` does not limit to `type`, `scope` and `subject`. They can now be defined in `options.headerCorrespondence` and the order is the order of capturing group in `options.headerPattern`. If part is missing in `options.headerCorrespondence` it is `undefined`. If part is not captured but is not missing in `options.headerCorrespondence` it is `null`.

Closes #10
  • Loading branch information
stevemao committed Apr 10, 2015
1 parent 5de792a commit a7e23a4
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 87 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Used to match header pattern.

Type: `array` of `string` or `string` Default `['type', 'scope', 'subject']`

Used to define what capturing group of `headerPattern` captures what header part. The order of the array should correspond to the order of `headerPattern`'s capturing group. If it's a `string` it will be converted to an `array` separated by a comma.
Used to define what capturing group of `headerPattern` captures what header part. The order of the array should correspond to the order of `headerPattern`'s capturing group. If the part is not captured it is `null`. If it's a `string` it will be converted to an `array` separated by a comma.

##### referenceKeywords

Expand Down
58 changes: 20 additions & 38 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,17 @@ function parser(raw, options, regex) {
var lines = _.compact(raw.split('\n'));
var continueNote = false;
var isBody = true;
var headerCorrespondence = _.map(options.headerCorrespondence, function(part) {
return part.trim();
});
var reNotes = regex.notes;
var reReferenceParts = regex.referenceParts;
var reReferences = regex.references;

function getHeadCorrespondence(part) {
var headerCorrespondence = options.headerCorrespondence
.map(function(val) {
return val.trim();
})
.filter(function(val) {
return val.length;
});
var index = _.indexOf(headerCorrespondence, part) + 1;
if (index === 0) {
throw new TypeError('Expected options.headerCorrespondence to only contain "type" "scope" or "subject"');
}

return index;
}

var typeIndex = getHeadCorrespondence('type');
var scopeIndex = getHeadCorrespondence('scope');
var subjectIndex = getHeadCorrespondence('subject');

// msg parts
var hash = lines[0];
var header = lines[1];
var type = null;
var scope = null;
var subject = null;
var headerParts = {};
var body = '';
var footer = '';
var notes = [];
Expand All @@ -66,15 +47,14 @@ function parser(raw, options, regex) {
headerMatch = header.match(options.headerPattern);

if (headerMatch) {
if (headerMatch[typeIndex]) {
type = headerMatch[typeIndex];
}
if (headerMatch[scopeIndex]) {
scope = headerMatch[scopeIndex];
}
if (headerMatch[subjectIndex]) {
subject = headerMatch[subjectIndex];
}
_.forEach(headerCorrespondence, function(partName, index) {
var partValue = headerMatch[index + 1] || null;
headerParts[partName] = partValue;
});
} else {
_.forEach(headerCorrespondence, function(partName) {
headerParts[partName] = null;
});
}

// incase people reference an issue in the header
Expand Down Expand Up @@ -160,17 +140,19 @@ function parser(raw, options, regex) {
footer = null;
}

return {
// don't change the order of fields
var msg = {
hash: hash,
header: header,
type: type,
scope: scope,
subject: subject,
header: header
};
msg = _.merge(msg, headerParts, {
body: body,
footer: footer,
notes: notes,
references: references
};
});

return msg;
}

module.exports = parser;
2 changes: 1 addition & 1 deletion test/expected/output3.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[
{"hash":"9b1aff905b638aa274a5fc8f88662df446d374bd","header":"category(fix:subcategory): My subject","type":"fix:subcategory","scope":"category","subject":"My subject","body":"This is my commit body.","footer":"BREAKING NEWS: A lot of changes!\nClose #10036, Closes #10000\nFixed #13233\nfix #9338","notes":[{"title":"BREAKING NEWS","text":"A lot of changes!"}],"references":[{"action":"Close","repository":null,"issue":"10036","raw":"#10036"},{"action":"fix","repository":null,"issue":"9338","raw":"#9338"}]}
{"hash":"9b1aff905b638aa274a5fc8f88662df446d374bd","header":"category(fix:subcategory): My subject","scope":"category","type":"fix:subcategory","subject":"My subject","body":"This is my commit body.","footer":"BREAKING NEWS: A lot of changes!\nClose #10036, Closes #10000\nFixed #13233\nfix #9338","notes":[{"title":"BREAKING NEWS","text":"A lot of changes!"}],"references":[{"action":"Close","repository":null,"issue":"10036","raw":"#10036"},{"action":"fix","repository":null,"issue":"9338","raw":"#9338"}]}
]
2 changes: 1 addition & 1 deletion test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ describe('conventionalCommitsParser', function() {
}))
.pipe(through.obj(function(chunk, enc, cb) {
if (--length === 1) {
expect(chunk.subject).to.equal('feat');
expect(chunk.type).to.equal('ng-list');
expect(chunk.scope).to.equal('Allow custom separator');
expect(chunk.subject).to.equal('feat');
expect(chunk.references).to.eql([{
action: 'Fix',
issue: '123',
Expand Down
62 changes: 16 additions & 46 deletions test/parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,17 @@ describe('parser', function() {
}).to.throw('Expected options');
});

it('type should be null if not found', function() {
expect(headerOnlyMsg.type).to.equal(null);
it('should allow ":" in scope', function() {
var msg = parser('feat(ng:list): Allow custom separator', {
headerPattern: /^(\w*)(?:\(([:\w\$\.\-\* ]*)\))?\: (.*)$/,
headerCorrespondence: ['type', 'scope', 'subject']
}, regex);
expect(msg.scope).to.equal('ng:list');
});

it('scope should be null if not found', function() {
it('header part should be null if not captured', function() {
expect(headerOnlyMsg.type).to.equal(null);
expect(headerOnlyMsg.scope).to.equal(null);
});

it('subject should be null if not found', function() {
expect(headerOnlyMsg.subject).to.equal(null);
});

Expand All @@ -125,44 +127,12 @@ describe('parser', function() {
expect(simpleMsg.header).to.equal('chore: some chore');
});

it('should parse type', function() {
it('should understand header parts', function() {
expect(msg.type).to.equal('feat');
});

it('should parse scope', function() {
expect(msg.scope).to.equal('scope');
});

it('should parse subject', function() {
expect(msg.subject).to.equal('broadcast $destroy event on scope destruction');
});

it('should parse header without a scope', function() {
expect(simpleMsg.header).to.equal('chore: some chore');
expect(simpleMsg.type).to.equal('chore');
expect(simpleMsg.scope).to.equal(null);
expect(simpleMsg.subject).to.equal('some chore');
});

it('should allow ":" in scope', function() {
var msg = parser('feat(ng:list): Allow custom separator', {
headerPattern: /^(\w*)(?:\(([:\w\$\.\-\* ]*)\))?\: (.*)$/,
headerCorrespondence: ['type', 'scope', 'subject']
}, regex);
expect(msg.scope).to.equal('ng:list');
});

it('should allow type and subject to be null', function() {
var msg = parser('(scope): ', {
headerPattern: /^(\w*)?(?:\(([\w\$\.\-\* ]*)\))?\: (.*)?$/,
headerCorrespondence: ['type', 'scope', 'subject']
}, regex);

expect(msg.type).to.equal(null);
expect(msg.scope).to.equal('scope');
expect(msg.subject).to.equal(null);
});

it('should allow correspondence to be changed', function() {
var msg = parser('scope(my subject): fix this', {
headerPattern: /^(\w*)(?:\(([\w\$\.\-\* ]*)\))?\: (.*)$/,
Expand All @@ -174,13 +144,13 @@ describe('parser', function() {
expect(msg.subject).to.equal('my subject');
});

it('should throw if headerCorrespondence contains illegal value', function() {
expect(function() {
parser('scope(my subject): fix this', {
headerPattern: /^(\w*)(?:\(([\w\$\.\-\* ]*)\))?\: (.*)$/,
headerCorrespondence: ['scop', 'subject', 'type']
}, regex);
}).to.throw('Expected options.headerCorrespondence to only contain "type" "scope" or "subject"');
it('should be undefined if it is missing in `options.headerCorrespondence`', function() {
msg = parser('scope(my subject): fix this', {
headerPattern: /^(\w*)(?:\(([\w\$\.\-\* ]*)\))?\: (.*)$/,
headerCorrespondence: ['scop', 'subject']
}, regex);

expect(msg.scope).to.equal(undefined);
});

it('should reference an issue', function() {
Expand Down

0 comments on commit a7e23a4

Please sign in to comment.