Skip to content

Instantly share code, notes, and snippets.

@epixa
Created December 28, 2015 15:12
Show Gist options
  • Save epixa/f62a2c40a4769b048ce2 to your computer and use it in GitHub Desktop.
Save epixa/f62a2c40a4769b048ce2 to your computer and use it in GitHub Desktop.
var _ = require('lodash');
var Promises = require('bluebird');
var exec = require('child_process').exec;
var semver = require('semver');
var join = require('path').join;
var ERR_UNKNOWN = 0;
var ERR_DOWNLOAD_FAILED = 1;
var ERR_ALREADY_EXISTS = 2;
var ERR_JAVA_PATH = 3;
function installCommand(path, plugin, oldCommand) {
var cmd = join(path, 'bin', 'plugin');
cmd += (oldCommand === true) ? ' --install ' : ' install ';
cmd += (_.isPlainObject(plugin)) ? plugin.name + ' --url ' + plugin.path : plugin;
return cmd;
}
function getErrorCause(stdout) {
if (stdout.match(new RegExp('failed to download', 'i'))) return ERR_DOWNLOAD_FAILED;
if (stdout.match(new RegExp('already exists', 'i'))) return ERR_ALREADY_EXISTS;
if (stdout.match(new RegExp('no such file or directory', 'i'))) return ERR_JAVA_PATH;
return ERR_UNKNOWN;
}
/**
* Install a plugin
* @param {object} options Options object
* @param {string} options.path The path of the install
* @param {mixed} options.plugin The plugin uri or an object with name and path to binary.
* @param {function} [options.log] The logger
* @returns {Promises}
*/
module.exports = function (options, cb) {
var log = options.log || _.noop;
var path = options.path;
var plugin = options.plugin;
var pluginName = (_.isPlainObject(plugin) ? plugin.name : plugin);
function handleInstallError(resolve, reject, stdout, fn) {
var errorCause = getErrorCause(stdout);
if (errorCause === ERR_DOWNLOAD_FAILED) {
var msg = 'Failed to download plugin: ' + pluginName + '\n' + stdout;
return reject(new Error(msg));
}
if (errorCause === ERR_JAVA_PATH) {
var msg = 'Can not find JAVA: ' + pluginName + '\n' + stdout;
return reject(new Error(msg));
}
if (errorCause === ERR_ALREADY_EXISTS) return resolve(true);
fn.call(fn);
}
log('INFO', 'Installing "'+ pluginName + '" plugin');
return new Promises(function (resolve, reject) {
exec(installCommand(path, plugin), function (err, stdout) {
if (!err) return resolve(stdout);
console.log('one', err, stdout);
handleInstallError(resolve, reject, stdout, function () {
exec(installCommand(path, plugin, true), function (err, stdout) {
if (!err) return resolve (stdout);
console.log('two', err, stdout);
handleInstallError(resolve, reject, stdout, function () {
// TODO: should probably handle other errors
resolve(true);
});
});
});
});
})
.nodeify(cb);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment