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