Skip to content

Update the commit template to receive more options #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,15 @@ You can configure the output of **gren** using templates. Set your own configura
```json
{
"template": {
"commit": "- {{message}}",
"commit": "- [{{message}}]({{url}}) - @{{author}}",
"issue": "- {{labels}} {{name}} [{{text}}]({{url}})",
"label": "[**{{label}}**]",
"noLabel": "closed",
"group": "\n#### {{heading}}\n",
"changelogTitle": "# Changelog\n\n",
"release": "## {{release}} {{date}}\n{{body}}",
"release": "## {{release}} ({{date}})\n{{body}}",
"releaseSeparator": "\n---\n\n"
}

}
```
{% endraw %}
Expand Down
5 changes: 5 additions & 0 deletions lib/_examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ module.exports = {
{
description: 'Otherwise, you can just filter the issues that belong to _a_ milestone',
code: 'gren release --only-milestones'
},
{
name: 'Use commit messages',
description: 'Generate release notes based on commit messages',
code: 'gren release --data-source=commits'
}
],
changelog: [
Expand Down
83 changes: 40 additions & 43 deletions lib/src/Gren.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,13 +370,16 @@ class Gren {
* @since 0.1.0
* @private
*
* @param {string} message
* @param {Object} commit
*
* @return {string}
*/
_templateCommits(message) {
_templateCommits({ sha, commit: { author: { name }, message, url } }) {
return generate({
message: message
sha,
message: message.split('\n')[0],
url,
author: name
}, this.options.template.commit);
}

Expand Down Expand Up @@ -470,64 +473,58 @@ class Gren {
}

/**
* Return a commit messages generated body
* Filter a commit based on the includeMessages option and commit message
*
* @since 0.1.0
* @since 0.10.0
* @private
*
* @param {Array} messages
* @param {Object} commit
*
* @return {string}
* @return {Boolean}
*/
_generateCommitsBody(messages = []) {
const bodyMessages = Array.from(messages);
_filterCommit({ commit: { message } }) {
const messageType = this.options.includeMessages;
const filterMap = {
merges: function(message) {
return message.match(/^merge/i);
},
commits: function(message) {
return !message.match(/^merge/i);
},
all: function() {
return true;
}
};

if (bodyMessages.length === 1) {
bodyMessages.push(null);
if (filterMap[messageType]) {
return filterMap[messageType](message);
}

return bodyMessages
.slice(0, -1)
.filter(message => {
const messageType = this.options.includeMessages;
const filterMap = {
merges: function(message) {
return message.match(/^merge/i);
},
commits: function(message) {
return !message.match(/^merge/i);
},
all: function() {
return true;
}
};

if (filterMap[messageType]) {
return filterMap[messageType](message);
}

return filterMap.commits(message);
})
.map(this._templateCommits.bind(this))
.join('\n');
return filterMap.commits(message);
}

/**
* Transforms the commits to commit messages
* Return a commit messages generated body
*
* @since 0.1.0
* @private
*
* @param {Object[]} commits The array of object containing the commits
* @param {Array} commits
*
* @return {String[]}
* @return {string}
*/
_commitMessages(commits = []) {
if (!Array.isArray(commits)) {
return [];
_generateCommitsBody(commits = []) {
const bodyMessages = Array.from(commits);

if (bodyMessages.length === 1) {
bodyMessages.push(null);
}

return commits.map(({ commit }) => commit && commit.message).filter(Boolean);
return bodyMessages
.slice(0, -1)
.filter(this._filterCommit.bind(this))
.map(this._templateCommits.bind(this))
.join('\n');
}

/**
Expand All @@ -551,7 +548,7 @@ class Gren {
};

return this.repo.listCommits(options)
.then(response => this._commitMessages(response.data));
.then(({ data }) => data);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/src/templates.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"commit": "- {{message}}",
"commit": "- [{{message}}]({{url}}) - @{{author}}",
"issue": "- {{labels}} {{name}} [{{text}}]({{url}})",
"label": "[**{{label}}**]",
"noLabel": "closed",
Expand Down
123 changes: 92 additions & 31 deletions test/Gren.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,35 +267,46 @@ describe('Gren', () => {
});
});

describe('_commitMessages', () => {
it('Should return an Array of strings', () => {
assert.isArray(gren._commitMessages([{ commit: { message: 'First body' }}, { commit: {message: 'Second body' }}]), 'Passing the Array of commits');
assert.deepEqual(gren._commitMessages([{ commit: { message: 'First body' }}, { commit: {message: 'Second body' }}]), ['First body', 'Second body'], 'Passing the Array of commits');
});

it('Should return an empty Array', () => {
assert.deepEqual(gren._commitMessages([]), [], 'Passing empty Array');
assert.deepEqual(gren._commitMessages([1, 2, 3]), [], 'Passing invalid Array');
assert.deepEqual(gren._commitMessages(false), [], 'Passing false');
assert.deepEqual(gren._commitMessages(true), [], 'Passing true');
assert.deepEqual(gren._commitMessages(), [], 'No parameters');
assert.deepEqual(gren._commitMessages('string'), [], 'Passing a string');
});
});

describe('_generateCommitsBody, _templateCommits', () => {
describe('_generateCommitsBody, _templateCommits, _filterCommit', () => {
let commitMessages;

before(() => {
gren.options.template.commit = '{{message}} - {{author}}';

commitMessages = [
"First commit",
"This is another commit",
"Merge branch into master: Something else here to be tested",
"This is the last one"
{
commit: {
message: 'First commit',
author: {
name: 'alexcanessa'
}
}
},
{
commit: {
message: 'This is another commit',
author: {
name: 'alexcanessa'
}
}
},
{
commit: {
message: 'Merge branch into master: Something else here to be tested',
author: {
name: 'alexcanessa'
}
}
},
{
commit: {
message: 'This is the last one',
author: {
name: 'alexcanessa'
}
}
}
];

// This makes the test easier
gren.options.template.commit = '{{message}}';
});

it('Should always return a string', () => {
Expand All @@ -307,21 +318,71 @@ describe('Gren', () => {
});

it('Should not return the last message', () => {
assert.notInclude(gren._generateCommitsBody(commitMessages), commitMessages.slice(-1)[0], 'Generate the messages');
assert.deepEqual(gren._generateCommitsBody(['One message']), 'One message', 'One message passed');
assert.deepEqual(gren._generateCommitsBody(['One', 'Two']), 'One', 'Two message passed');
assert.deepEqual(gren._generateCommitsBody(['One', 'Two', 'Three']), 'One\nTwo', 'Three message passed');
const lastMessage = commitMessages.slice(-1)[0];

assert.notInclude(gren._generateCommitsBody(commitMessages), `${lastMessage.commit.message} - ${lastMessage.commit.author.name}`, 'Generate the messages');
assert.deepEqual(gren._generateCommitsBody([{
commit: {
message: 'One message',
author: {
name: 'alexcanessa'
}
}
}]), 'One message - alexcanessa', 'One message passed');
assert.deepEqual(gren._generateCommitsBody([{
commit: {
message: 'One',
author: {
name: 'alexcanessa'
}
}
},
{
commit: {
message: 'Two',
author: {
name: 'alexcanessa'
}
}
}]), 'One - alexcanessa', 'Two message passed');
assert.deepEqual(gren._generateCommitsBody([{
commit: {
message: 'One',
author: {
name: 'alexcanessa'
}
}
},
{
commit: {
message: 'Two',
author: {
name: 'alexcanessa'
}
}
},
{
commit: {
message: 'Three',
author: {
name: 'alexcanessa'
}
}
}]), 'One - alexcanessa\nTwo - alexcanessa', 'Three message passed');
});

it('Should only return the messages defined in the options', () => {
gren.options.includeMessages = 'commits';
assert.deepEqual(gren._generateCommitsBody(commitMessages), `${commitMessages[0]}\n${commitMessages[1]}`, 'Using commits as includeMessages');

const messages = msg => `${commitMessages[msg].commit.message} - ${commitMessages[msg].commit.author.name}`;

assert.deepEqual(gren._generateCommitsBody(commitMessages), `${messages(0)}\n${messages(1)}`, 'Using commits as includeMessages');

gren.options.includeMessages = 'all';
assert.deepEqual(gren._generateCommitsBody(commitMessages), `${commitMessages[0]}\n${commitMessages[1]}\n${commitMessages[2]}`, 'Using commits as includeMessages');
assert.deepEqual(gren._generateCommitsBody(commitMessages), `${messages(0)}\n${messages(1)}\n${messages(2)}`, 'Using commits as includeMessages');

gren.options.includeMessages = 'merges';
assert.deepEqual(gren._generateCommitsBody(commitMessages), commitMessages[2], 'Using commits as includeMessages');
assert.deepEqual(gren._generateCommitsBody(commitMessages), messages(2), 'Using commits as includeMessages');
});
});

Expand Down