Нема описа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

changelog.js 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. "use strict";
  2. var path = require("path"),
  3. fs = require("fs");
  4. var gitSemverTags = require("git-semver-tags"),
  5. gitRawCommits = require("git-raw-commits"),
  6. minimist = require("minimist");
  7. var basedir = path.join(__dirname, "..");
  8. var pkg = require(basedir + "/package.json");
  9. var argv = minimist(process.argv, {
  10. alias: {
  11. tag : "t",
  12. write : "w"
  13. },
  14. string: [ "tag" ],
  15. boolean: [ "write" ],
  16. default: {
  17. tag: null,
  18. write: false
  19. }
  20. });
  21. // categories to be used in the future and regexes for lazy / older subjects
  22. var validCategories = {
  23. "Breaking": null,
  24. "Fixed": /fix|properly|prevent|correctly/i,
  25. "New": /added|initial/i,
  26. "CLI": /pbjs|pbts|CLI/,
  27. "Docs": /README/i,
  28. "Other": null
  29. };
  30. var breakingFallback = /removed|stripped|dropped/i;
  31. var repo = "https://github.com/protobufjs/protobuf.js";
  32. gitSemverTags(function(err, tags) {
  33. if (err)
  34. throw err;
  35. var categories = {};
  36. Object.keys(validCategories).forEach(function(category) {
  37. categories[category] = [];
  38. });
  39. var output = [];
  40. var from = tags[0];
  41. var to = "HEAD";
  42. var tag;
  43. if (argv.tag) {
  44. var idx = tags.indexOf(argv.tag);
  45. if (idx < 0)
  46. throw Error("no such tag: " + argv.tag);
  47. from = tags[idx + 1];
  48. tag = to = tags[idx];
  49. } else
  50. tag = pkg.version;
  51. var commits = gitRawCommits({
  52. from: from,
  53. to: to,
  54. merges: false,
  55. format: "%B%n#%H"
  56. });
  57. commits.on("error", function(err) {
  58. throw err;
  59. });
  60. commits.on("data", function(chunk) {
  61. var message = chunk.toString("utf8").trim();
  62. var match = /##([0-9a-f]{40})$/.exec(message);
  63. var hash;
  64. if (match) {
  65. message = message.substring(0, message.length - match[1].length).trim();
  66. hash = match[1];
  67. }
  68. message.split(";").forEach(function(message) {
  69. if (/^(Merge pull request |Post-merge)/.test(message))
  70. return;
  71. var match = /^(\w+):/i.exec(message = message.trim());
  72. var category;
  73. if (match && match[1] in validCategories) {
  74. category = match[1];
  75. message = message.substring(match[1].length + 1).trim();
  76. } else {
  77. var keys = Object.keys(validCategories);
  78. for (var i = 0; i < keys.length; ++i) {
  79. var re = validCategories[keys[i]];
  80. if (re && re.test(message)) {
  81. category = keys[i];
  82. break;
  83. }
  84. }
  85. message = message.replace(/^(\w+):/i, "").trim();
  86. }
  87. if (!category) {
  88. if (breakingFallback.test(message))
  89. category = "Breaking";
  90. else
  91. category = "Other";
  92. }
  93. var nl = message.indexOf("\n");
  94. if (nl > -1)
  95. message = message.substring(0, nl).trim();
  96. if (!hash || message.length < 12)
  97. return;
  98. message = message.replace(/\[ci skip\]/, "").trim();
  99. categories[category].push({
  100. text: message,
  101. hash: hash
  102. });
  103. });
  104. });
  105. commits.on("end", function() {
  106. output.push("## [" + tag + "](" + repo + "/releases/tag/" + tag + ")\n");
  107. Object.keys(categories).forEach(function(category) {
  108. var messages = categories[category];
  109. if (!messages.length)
  110. return;
  111. output.push("\n### " + category + "\n");
  112. messages.forEach(function(message) {
  113. var text = message.text.replace(/#(\d+)/g, "[#$1](" + repo + "/issues/$1)");
  114. output.push("[:hash:](" + repo + "/commit/" + message.hash + ") " + text + "<br />\n");
  115. });
  116. });
  117. var current;
  118. try {
  119. current = fs.readFileSync(basedir + "/CHANGELOG.md").toString("utf8");
  120. } catch (e) {
  121. current = "";
  122. }
  123. var re = new RegExp("^## \\[" + tag + "\\]");
  124. if (re.test(current)) { // regenerated, replace
  125. var pos = current.indexOf("## [", 1);
  126. if (pos > -1)
  127. current = current.substring(pos).trim();
  128. else
  129. current = "";
  130. }
  131. var contents = output.join("") + "\n" + current;
  132. if (argv.write)
  133. fs.writeFileSync(basedir + "/CHANGELOG.md", contents, "utf8");
  134. else
  135. process.stdout.write(contents);
  136. });
  137. });