util.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. var fs = require('fs');
  2. var changelog, latest, nextReleaseFiles;
  3. var changelogFile = process.cwd() + '/CHANGELOG.md';
  4. var changesDir = process.cwd() + '/.changes/';
  5. var nextReleaseDir = changesDir + 'next-release/';
  6. var insertMarker = '<!--ENTRYINSERT-->';
  7. var versionMarker = ['<!--LATEST=', '-->'];
  8. var startContent = '# Changelog for AWS SDK for JavaScript\n' +
  9. versionMarker.join('0.0.0') + '\n' + insertMarker;
  10. var versionRegStr = '(\\d+)\\.(\\d+)\\.(\\d+)';
  11. var versionReg = new RegExp('^' + versionRegStr + '$');
  12. var versionMarkerReg = new RegExp(versionMarker.join(versionRegStr));
  13. var versionJsonFileReg = new RegExp('^' + versionRegStr + '\\.json$');
  14. function fsSyncFromRoot(operation, fileOrDir) {
  15. try {
  16. var result = fs[operation + 'Sync'](fileOrDir);
  17. } catch(err) {
  18. if (err.code === 'ENOENT') {
  19. err.message += '. Make sure to run from sdk root directory'
  20. }
  21. throw err;
  22. }
  23. return result;
  24. }
  25. function readChangelog() {
  26. changelog = fsSyncFromRoot('readFile', changelogFile).toString();
  27. return changelog;
  28. }
  29. function getLatestVersion() {
  30. if (!changelog) readChangelog();
  31. var match = changelog.match(versionMarkerReg);
  32. latest = {
  33. major: parseInt(match[1],10),
  34. minor: parseInt(match[2],10),
  35. patch: parseInt(match[3],10)
  36. };
  37. return latest;
  38. }
  39. function checkAndNormalizeVersion(version) {
  40. if (!latest) getLatestVersion();
  41. var match = version.match(versionReg);
  42. if (match) {
  43. // convert to num for comparison and for normalizing leading zeros
  44. var major = parseInt(match[1], 10);
  45. var minor = parseInt(match[2], 10);
  46. var patch = parseInt(match[3], 10);
  47. if (major < latest.major ||
  48. major == latest.major && minor < latest.minor ||
  49. major == latest.major && minor == latest.minor && patch <= latest.patch) {
  50. throw new Error('Version must be greater than latest version');
  51. }
  52. return major + '.' + minor + '.' + patch;
  53. } else {
  54. throw new Error('Provided input version is in wrong format');
  55. }
  56. }
  57. function bumpMajor() {
  58. if (!latest) getLatestVersion();
  59. return (latest.major + 1) + '.0.0';
  60. }
  61. function bumpMinor() {
  62. if (!latest) getLatestVersion();
  63. return latest.major + '.' + (latest.minor + 1) + '.0';
  64. }
  65. function bumpPatch() {
  66. if (!latest) getLatestVersion();
  67. return latest.major + '.' + latest.minor + '.' + (latest.patch + 1);
  68. }
  69. function listVersions() {
  70. var changeFiles = fsSyncFromRoot('readdir', changesDir);
  71. return changeFiles
  72. .map(function(file) { return file.match(versionJsonFileReg); })
  73. .filter(function(version) { return !!version; })
  74. .sort(function(v1, v2) {
  75. var diff;
  76. for (var i = 1; i <= 3; i++) {
  77. diff = v1[i] - v2[i];
  78. if (diff !== 0) {
  79. return diff;
  80. }
  81. }
  82. return 0;
  83. })
  84. .map(function(version) { return version.slice(1).join('.'); });
  85. }
  86. function listNextReleaseFiles() {
  87. nextReleaseFiles = fsSyncFromRoot('readdir', nextReleaseDir)
  88. .map(function(file) { return nextReleaseDir + file });
  89. if (!nextReleaseFiles.length) throw new Error('No changes to be released');
  90. return nextReleaseFiles;
  91. }
  92. function startNewChangelog() {
  93. changelog = startContent;
  94. return changelog;
  95. }
  96. function checkChangeFormat(change) {
  97. if (!change.type || !change.category || !change.description ||
  98. typeof change.type !== 'string' ||
  99. typeof change.category !== 'string' ||
  100. typeof change.description !== 'string') {
  101. var err = new Error('JSON not in correct format');
  102. err.code = 'InvalidFormat';
  103. throw err;
  104. }
  105. }
  106. function readChangesFromJSON(filepath) {
  107. var changes = JSON.parse(fsSyncFromRoot('readFile', filepath));
  108. if (!Array.isArray(changes)) changes = [changes];
  109. if (!changes.length) throw new Error(filepath + ' contains no changes');
  110. try {
  111. changes.forEach(checkChangeFormat);
  112. } catch (err) {
  113. if (err.code === 'InvalidFormat') {
  114. err.message += ' in ' + filepath;
  115. }
  116. throw err;
  117. }
  118. return changes;
  119. }
  120. // This will not to write to file
  121. // writeToChangelog must be called after
  122. function addVersionJSONToChangelog(version, changes) {
  123. if (!changelog) readChangelog();
  124. var entry = '\n\n## ' + version;
  125. changes.forEach(function(change) {
  126. entry += '\n* ' + change.type + ': ' + change.category + ': ' +
  127. change.description;
  128. });
  129. var logParts = changelog.split(insertMarker);
  130. logParts[0] = logParts[0]
  131. .replace(versionMarkerReg, versionMarker.join(version)) + insertMarker;
  132. changelog = logParts.join(entry);
  133. }
  134. // This will not to write to file
  135. // writeToChangelog must be called after
  136. function readVersionJSONAndAddToChangelog(version) {
  137. var changes = readChangesFromJSON(changesDir + version + '.json');
  138. addVersionJSONToChangelog(version, changes);
  139. }
  140. function writeToChangelog() {
  141. if (!changelog) throw new Error('Nothing to write');
  142. fs.writeFileSync(changelogFile, changelog);
  143. console.log('Successfully updated CHANGELOG');
  144. }
  145. function writeToVersionJSON(version, json) {
  146. var content = JSON.stringify(json, null, 4);
  147. fs.writeFileSync(changesDir + version + '.json', content);
  148. console.log('Successfully added ' + version + '.json to ' + changesDir);
  149. }
  150. function clearNextReleaseDir() {
  151. if (!nextReleaseFiles) listNextReleaseFiles();
  152. nextReleaseFiles.forEach(function(filepath) {
  153. fsSyncFromRoot('unlink', filepath);
  154. });
  155. console.log(nextReleaseDir + ' has been cleared');
  156. }
  157. module.exports = {
  158. readChangelog: readChangelog,
  159. getLatestVersion: getLatestVersion,
  160. checkAndNormalizeVersion: checkAndNormalizeVersion,
  161. bumpMajor: bumpMajor,
  162. bumpMinor: bumpMinor,
  163. bumpPatch: bumpPatch,
  164. listVersions: listVersions,
  165. listNextReleaseFiles: listNextReleaseFiles,
  166. startNewChangelog: startNewChangelog,
  167. readChangesFromJSON: readChangesFromJSON,
  168. addVersionJSONToChangelog: addVersionJSONToChangelog,
  169. readVersionJSONAndAddToChangelog: readVersionJSONAndAddToChangelog,
  170. writeToChangelog: writeToChangelog,
  171. writeToVersionJSON: writeToVersionJSON,
  172. clearNextReleaseDir: clearNextReleaseDir
  173. };