Skip to content

Commit

Permalink
chore(build): create CHANGELOG.md file from commit log
Browse files Browse the repository at this point in the history
Create changes log from git log automatically.
Replaced grunt-gitinfo to use grunt-exec.

Ref g-17
  • Loading branch information
netil committed Nov 5, 2015
1 parent 9f8cca8 commit eeaae97
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 6 deletions.
4 changes: 3 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ module.exports = function(grunt) {

var config = {
"pkg": grunt.file.readJSON("package.json"),
"gitinfo": grunt.task.run("gitinfo"),
"gitinfo": grunt.task.run("exec:gitinfo"),
"banner": getConfig("banner"),
"exec": getConfig("exec"),
"concat": getConfig("concat"),
"copy": getConfig("copy"),
"jscs": getConfig("jscs"),
Expand Down Expand Up @@ -52,4 +53,5 @@ module.exports = function(grunt) {
// grunt.registerTask("build", ["concat", "uglify", "copy:lib", "docBuild"]);
grunt.registerTask("default", ["jshint", "jscs", "build", "test"]);
grunt.registerTask("check", ["jscs"]);
grunt.registerTask("changelog", ["exec:changelog"]);
};
6 changes: 3 additions & 3 deletions config/banner.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module.exports = ["/**",
"* <%= pkg.name %>",
"* @version <%= pkg.version %>",
"* @SHA-1 <%= gitinfo.local.branch.current.shortSHA %>" +
"<%= /(?!^master$)(^.*$)/.test(gitinfo.local.branch.current.name) " +
"* @SHA-1 <%= gitinfo.shortSHA %>" +
"<%= /(?!^master$)(^.*$)/.test(gitinfo.branchName) " +
" && ' ('+ RegExp.$1 +')' || '' %>",
"*",
"* <%= pkg.author %>; <%= pkg.name %> JavaScript library",
"* http://egjs.navercorp.com/",
"*",
"* Released under the <%= pkg.licenses[0].type %> license",
"* <%= pkg.licenses[0].url %>",
"*/\n"].join("\n");
"*/\n\n"].join("\n");
142 changes: 142 additions & 0 deletions config/exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
module.exports = {
// create changelog
changelog: {
after: "2015-09-25",
before: "",
cmd: function() {
var before = this.config("exec.changelog.before") || this.template.today("yyyy-mm-dd");

return [
"git log",
"--grep=feat",
"--grep=fix",
"-i",
"--after={" + this.config("exec.changelog.after") + "}",
"--before={" + before + "}",
"--pretty=\"<item><hash>%h</hash><subject>%s</subject><body><![CDATA[%b]]></body></item>\"",
"--no-merges"
].join(" ");
},
callback: function(error, stdout, stderr) {
var grunt = require("grunt");
var xml2js = require("xml2js");
var parser = new xml2js.Parser();
var logdata = {
feat: {},
fix: {}
};

var isDuplicated = function(data, val) {
for (var i = 0, el; el = data[i]; i++) {
if (el.subject === val ) {
return true;
}
}

return false;
};

parser.parseString("<logs>" + stdout + "</logs>", function(err, result) {
if (!result || !result.logs) {
return;
}

var rxNewline = /\r?\n/g;
var rxBody = /ref\s[#yg]-?([0-9]+)$/i;
var rxSubject = /^(fix|feat)\s?\((\w+)\)\s*:\s*(.*)/i;
var issue, subject, category;

for (var i = 0, el; el = result.logs.item[i]; i++) {

// filter logs which has issue reference on commit body message.
issue = el.body[0].replace(rxNewline, "").match(rxBody);

if (issue) {
subject = el.subject[0].match(rxSubject);

// filter subject which matches with fix or feat format
if (subject) {
category = logdata[subject[1]];

if (!category[subject[2]]) {
category[subject[2]] = [];
}

// filter duplicated subject
if (!isDuplicated(category[subject[2]], subject[3])) {
category[subject[2]].push({
subject: subject[3],
issue: issue[1],
hash: el.hash[0]
});
}
}
}
}
});

// template for content of CHANGELOG.md
var template = {
header: "# <%= version%> release (<%= date %>)\r\n",
category: "\r\n## <%= category %> :\r\n",
module: "\r\n- **<%= module %>**\r\n",
item: [
"\t- <%= subject %> ([<%= issue %>](",
grunt.config("pkg.bugs.url"),
"/<%= issue %>) / [<%= hash %>](",
grunt.config("pkg.repository.url"),
"/commit/<%= hash %>))\r\n"
].join("")
}

var markdown = grunt.template.process(template.header, { data: {
version: grunt.config("pkg.version"),
date: grunt.config("gitinfo.lastCommitTime")
}});

for (var x in logdata) {
markdown += grunt.template.process(template.category, { data: {
category: x === "feat" && "Features" || x === "fix" && "Bug Fixes" || ""
}});

for (var z in logdata[x]) {
markdown += grunt.template.process(template.module, { data: {
module: z
}});

for (var i = 0, el; el = logdata[x][z][i]; i++) {
markdown += grunt.template.process(template.item, { data: {
subject: el.subject,
issue: el.issue,
hash: el.hash
}});
}
}
}

grunt.file.write("CHANGELOG.md", markdown, { encoding: "UTF-8" });
},
stdout: false
},

// get git info
gitinfo: {
cmd: function() {
return [
"git rev-parse --abbrev-ref HEAD",
"&&"
,"git log -1 --pretty=\"format:%h %ci\" --no-merges"
].join(" ");
},
callback: function(error, stdout, stderr) {
var info = stdout.replace(/\r?\n/," ").split(" ");

require("grunt").config.set("gitinfo", {
branchName: info[0],
shortSHA: info[1],
lastCommitTime: info[2]
});
},
stdout: false
}
};
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@
"grunt-contrib-qunit": "^0.7.0",
"grunt-contrib-uglify": "^0.8.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-gitinfo": "^0.1.7",
"grunt-exec": "^0.4.6",
"grunt-jscs": "^2.1.0",
"grunt-jsdoc": "^0.5.8",
"grunt-qunit-istanbul": "^0.5.0",
"jshint-stylish": "^1.0.1",
"jsonfile": "^2.2.3",
"load-grunt-tasks": "^3.1.0",
"testee": "^0.2.0",
"time-grunt": "^1.1.0",
"jsonfile": "^2.2.3"
"xml2js": "^0.4.15"
}
}

0 comments on commit eeaae97

Please sign in to comment.