git-off

git off handles large files in git repos
git clone https://noulin.net/git/git-off.git
Log | Files | Refs | README

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 };