UNPKG

urban-airship-cli

Version:

Command line interface for push notifications.

312 lines (232 loc) 7.94 kB
var colors = require('colors'); var program = require('commander'); var exec = require('child_process').exec; var fs = require('fs'); var Q = require('q'); var arguments = process.argv; var package = require('./package'); var stages = { verifyBranch: { action: function (data) { var deferred = Q.defer(); exec('git branch', function (error, stdout, stderr) { if (error) return deferred.reject({stage: stages.verifyBranch, data: data, message: error}); if (stdout.indexOf('* master') < 0) return deferred.reject({stage: stages.verifyBranch, data: data, message: 'You must be in master'}); deferred.resolve(data); }); return deferred.promise; }, onFailure: function (data) { var deferred = Q.defer(); deferred.resolve(data); return deferred.promise; }, }, pumpVersion: { action: function (data) { var deferred = Q.defer(); var packageRaw = JSON.stringify(package, null, 2); fs.writeFile('package.json', packageRaw.replace(data.oldVersion, data.newVersion), function (error) { if (error) return deferred.reject({stage: stages.pumpVersion, data: data, message: error}); console.log('version up:'.green, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, onFailure: function (data) { var deferred = Q.defer(); var packageRaw = JSON.stringify(package, null, 2); fs.writeFile('package.json', packageRaw.replace(data.newVersion, data.oldVersion), function (error) { console.log('version revert:'.red, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, }, commitVersion: { action: function (data) { var deferred = Q.defer(); exec('git commit -m "version: pump version to ' + data.newVersion + '" package.json', function (error, stdout, stderr) { if (error) return deferred.reject({stage: stages.commitVersion, data: data, message: error}); console.log('commit package:'.green, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, onFailure: function (data) { var deferred = Q.defer(); exec('git reset --soft HEAD~', function (error, stdout, stderr) { console.log('revert commit:'.red, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, }, pushVersion: { action: function (data) { var deferred = Q.defer(); exec('git push origin master', function (error, stdout, stderr) { if (error) return deferred.reject({stage: stages.pushVersion, data: data, message: error}); console.log('push package:'.green, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, onFailure: function (data) { var deferred = Q.defer(); exec('git reset --hard HEAD@{1}', function (error, stdout, stderr) { console.log('revert push:'.red, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, }, tagVersion: { action: function (data) { var deferred = Q.defer(); var tagVersion = 'v' + data.newVersion; exec('git tag -m "' + tagVersion + '" ' + tagVersion, function (error, stdout, stderr) { if (error) return deferred.reject({stage: stages.tagVersion, data: data, message: error}); console.log('tag:'.green, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, onFailure: function (data) { var deferred = Q.defer(); var tagVersion = 'v' + data.newVersion; exec('git tag --delete ' + tagVersion, function (error, stdout, stderr) { console.log('revert tag:'.red, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, }, pushRelease: { action: function (data) { var deferred = Q.defer(); exec('git push origin --tags', function (error, stdout, stderr) { if (error) return deferred.reject({stage: stages.pushRelease, data: data, message: error}); console.log('push:'.green, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, onFailure: function (data) { var deferred = Q.defer(); var tagVersion = 'v' + data.newVersion; exec('git push --delete origin ' + tagVersion, function (error, stdout, stderr) { console.log('pop release:'.red, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, }, publishVersion: { action: function (data) { var deferred = Q.defer(); exec('npm publish', function (error, stdout, stderr) { if (error) return deferred.reject({stage: stages.publishVersion, data: data, message: error}); console.log('publish:'.green, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; }, onFailure: function (data) { var deferred = Q.defer(); exec('npm unpublish urban-airship-cli@' + data.newVersion, function (error, stdout, stderr) { console.log('unpublish:'.red, 'ok'.bold); deferred.resolve(data); }); return deferred.promise; } }, }; function deployFailureHandler (error) { if (!error) return console.log('deploy success!'); console.log('\nDeploy failed: reverting'.bold.red, error.data.newVersion, '~>'.bold.red, error.data.oldVersion, error.message, '\n'); switch (error.stage) { case stages.verifyBranch: stages.verifyBranch.onFailure(error.data); break; case stages.pumpVersion: stages.verifyBranch.onFailure(error.data) .then(stages.pumpVersion.onFailure); break; case stages.commitVersion: stages.verifyBranch.onFailure(error.data) .then(stages.pumpVersion.onFailure) .then(stages.commitVersion.onFailure); break; case stages.pushVersion: stages.verifyBranch.onFailure(error.data) .then(stages.pumpVersion.onFailure) .then(stages.commitVersion.onFailure) .then(stages.pushVersion.onFailure); break; case stages.tagVersion: stages.verifyBranch.onFailure(error.data) .then(stages.pumpVersion.onFailure) .then(stages.commitVersion.onFailure) .then(stages.pushVersion.onFailure) .then(stages.tagVersion.onFailure); break; case stages.pushRelease: stages.verifyBranch.onFailure(error.data) .then(stages.pumpVersion.onFailure) .then(stages.commitVersion.onFailure) .then(stages.pushVersion.onFailure) .then(stages.tagVersion.onFailure) .then(stages.pushRelease.onFailure); break; case stages.publishVersion: stages.verifyBranch.onFailure(error.data) .then(stages.pumpVersion.onFailure) .then(stages.commitVersion.onFailure) .then(stages.pushVersion.onFailure) .then(stages.tagVersion.onFailure) .then(stages.pushRelease.onFailure) .then(stages.publishVersion.onFailure); break; } } program .command('deploy <version>') .description('version format: <major>.<minor>.<patch>') .action(function deploy (version) { var data = {}; if (!version.match(/^[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}$/)) { console.log('Invalid version format:'.bold.red, version); return program.outputHelp(); } data.newVersion = version; data.oldVersion = package.version; data.newVersionNumber = Number(data.newVersion.split('.').join('')); data.oldVersionNumber = Number(data.oldVersion.split('.').join('')); if (data.oldVersionNumber > data.newVersionNumber) { return console.log('Invalid version: Old version is greater than the new version - '.bold.red, data.oldVersion, '>'.bold.red, data.newVersion); } console.log('Deploying:'.bold.green, data.oldVersion, '~>'.bold.green, data.newVersion, '\n'); stages.verifyBranch.action(data) .then(stages.pumpVersion.action) .then(stages.commitVersion.action) .then(stages.pushVersion.action) .then(stages.tagVersion.action) .then(stages.pushRelease.action) .then(stages.publishVersion.action) .catch(deployFailureHandler) .done(); }) program.parse(arguments);