tra-analysis/website/functions/node_modules/protobufjs/scripts/changelog.js
2019-01-06 13:14:45 -06:00

151 lines
4.5 KiB
JavaScript

"use strict";
var path = require("path"),
fs = require("fs");
var gitSemverTags = require("git-semver-tags"),
gitRawCommits = require("git-raw-commits"),
minimist = require("minimist");
var basedir = path.join(__dirname, "..");
var pkg = require(basedir + "/package.json");
var argv = minimist(process.argv, {
alias: {
tag : "t",
write : "w"
},
string: [ "tag" ],
boolean: [ "write" ],
default: {
tag: null,
write: false
}
});
// categories to be used in the future and regexes for lazy / older subjects
var validCategories = {
"Breaking": null,
"Fixed": /fix|properly|prevent|correctly/i,
"New": /added|initial/i,
"CLI": /pbjs|pbts|CLI/,
"Docs": /README/i,
"Other": null
};
var breakingFallback = /removed|stripped|dropped/i;
var repo = "https://github.com/dcodeIO/protobuf.js";
gitSemverTags(function(err, tags) {
if (err)
throw err;
var categories = {};
Object.keys(validCategories).forEach(function(category) {
categories[category] = [];
});
var output = [];
var from = tags[0];
var to = "HEAD";
var tag;
if (argv.tag) {
var idx = tags.indexOf(argv.tag);
if (idx < 0)
throw Error("no such tag: " + argv.tag);
from = tags[idx + 1];
tag = to = tags[idx];
} else
tag = pkg.version;
var commits = gitRawCommits({
from: from,
to: to,
merges: false,
format: "%B%n#%H"
});
commits.on("error", function(err) {
throw err;
});
commits.on("data", function(chunk) {
var message = chunk.toString("utf8").trim();
var match = /#([0-9a-f]{40})$/.exec(message);
var hash;
if (match) {
message = message.substring(0, message.length - match[1].length).trim();
hash = match[1];
}
message.split(";").forEach(function(message) {
if (/^(Merge pull request |Post-merge)/.test(message))
return;
var match = /^(\w+):/i.exec(message = message.trim());
var category;
if (match && match[1] in validCategories) {
category = match[1];
message = message.substring(match[1].length + 1).trim();
} else {
var keys = Object.keys(validCategories);
for (var i = 0; i < keys.length; ++i) {
var re = validCategories[keys[i]];
if (re && re.test(message)) {
category = keys[i];
break;
}
}
message = message.replace(/^(\w+):/i, "").trim();
}
if (!category) {
if (breakingFallback.test(message))
category = "Breaking";
else
category = "Other";
}
var nl = message.indexOf("\n");
if (nl > -1)
message = message.substring(0, nl).trim();
if (!hash || message.length < 12)
return;
message = message.replace(/\[ci skip\]/, "").trim();
categories[category].push({
text: message,
hash: hash
});
});
});
commits.on("end", function() {
output.push("# [" + tag + "](" + repo + "/releases/tag/" + tag + ")\n");
Object.keys(categories).forEach(function(category) {
var messages = categories[category];
if (!messages.length)
return;
output.push("\n## " + category + "\n");
messages.forEach(function(message) {
var text = message.text.replace(/#(\d+)/g, "[#$1](" + repo + "/issues/$1)");
output.push("[:hash:](" + repo + "/commit/" + message.hash + ") " + text + "<br />\n");
});
});
var current;
try {
current = fs.readFileSync(basedir + "/CHANGELOG.md").toString("utf8");
} catch (e) {
current = "";
}
var re = new RegExp("^# \\[" + tag + "\\]");
if (re.test(current)) { // regenerated, replace
var pos = current.indexOf("# [", 1);
if (pos > -1)
current = current.substring(pos).trim();
else
current = "";
}
var contents = output.join("") + "\n" + current;
if (argv.write)
fs.writeFileSync(basedir + "/CHANGELOG.md", contents, "utf8");
else
process.stdout.write(contents);
});
});