CLI fixes for installing and removing services.
This commit is contained in:
parent
5e532d4b78
commit
52e80039d8
30
cli/main.js
30
cli/main.js
|
@ -58,20 +58,23 @@ function main() {
|
|||
});
|
||||
|
||||
program
|
||||
.command('add <modules...>')
|
||||
.command('add <services...>')
|
||||
.alias('install')
|
||||
.description('Install a module for the current node')
|
||||
.action(function(modules){
|
||||
.description('Install a service for the current node')
|
||||
.action(function(services){
|
||||
var configInfo = findConfig(process.cwd());
|
||||
if (!configInfo) {
|
||||
throw new Error('Could not find configuration, see `bitcore-node create --help`');
|
||||
}
|
||||
var opts = {
|
||||
path: configInfo.path,
|
||||
modules: modules
|
||||
services: services
|
||||
};
|
||||
add(opts, function() {
|
||||
console.log('Successfully added module(s):', modules.join(', '));
|
||||
add(opts, function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
console.log('Successfully added services(s):', services.join(', '));
|
||||
});
|
||||
}).on('--help', function() {
|
||||
console.log(' Examples:');
|
||||
|
@ -82,20 +85,23 @@ function main() {
|
|||
});
|
||||
|
||||
program
|
||||
.command('remove <modules...>')
|
||||
.command('remove <services...>')
|
||||
.alias('uninstall')
|
||||
.description('Uninstall a module for the current node')
|
||||
.action(function(modules){
|
||||
.description('Uninstall a service for the current node')
|
||||
.action(function(services){
|
||||
var configInfo = findConfig(process.cwd());
|
||||
if (!configInfo) {
|
||||
throw new Error('Could not find configuration, see `bitcore-node create --help`');
|
||||
}
|
||||
var opts = {
|
||||
path: configInfo.path,
|
||||
modules: modules
|
||||
services: services
|
||||
};
|
||||
remove(opts, function() {
|
||||
console.log('Successfully removed module(s):', modules.join(', '));
|
||||
remove(opts, function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
console.log('Successfully removed services(s):', services.join(', '));
|
||||
});
|
||||
}).on('--help', function() {
|
||||
console.log(' Examples:');
|
||||
|
|
|
@ -147,11 +147,6 @@ Node.prototype._instantiateService = function(service) {
|
|||
config.node = this;
|
||||
var mod = new service.module(config);
|
||||
|
||||
$.checkState(
|
||||
mod instanceof BaseService,
|
||||
'Unexpected module instance type for service:' + service.name
|
||||
);
|
||||
|
||||
// include in loaded services
|
||||
this.services[service.name] = mod;
|
||||
|
||||
|
|
|
@ -94,6 +94,11 @@ function add(options, done) {
|
|||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
// TODO: get the name of the package from the updated package.json
|
||||
// to be able to support other types of installation such as
|
||||
// hosted git urls
|
||||
|
||||
// add service to bitcore-node.json
|
||||
addConfig(bitcoreConfigPath, service, next);
|
||||
});
|
||||
|
|
|
@ -10,12 +10,12 @@ var $ = bitcore.util.preconditions;
|
|||
var _ = bitcore.deps._;
|
||||
|
||||
/**
|
||||
* Will remove a module from bitcore-node.json
|
||||
* Will remove a service from bitcore-node.json
|
||||
* @param {String} configFilePath - The absolute path to the configuration file
|
||||
* @param {String} module - The name of the module
|
||||
* @param {String} service - The name of the module
|
||||
* @param {Function} done
|
||||
*/
|
||||
function removeConfig(configFilePath, module, done) {
|
||||
function removeConfig(configFilePath, service, done) {
|
||||
$.checkArgument(path.isAbsolute(configFilePath), 'An absolute path is expected');
|
||||
fs.readFile(configFilePath, function(err, data) {
|
||||
if (err) {
|
||||
|
@ -23,17 +23,17 @@ function removeConfig(configFilePath, module, done) {
|
|||
}
|
||||
var config = JSON.parse(data);
|
||||
$.checkState(
|
||||
Array.isArray(config.modules),
|
||||
'Configuration file is expected to have a modules array.'
|
||||
Array.isArray(config.services),
|
||||
'Configuration file is expected to have a services array.'
|
||||
);
|
||||
// remove the module from the configuration
|
||||
for (var i = 0; i < config.modules.length; i++) {
|
||||
if (config.modules[i] === module) {
|
||||
config.modules.splice(i, 1);
|
||||
// remove the service from the configuration
|
||||
for (var i = 0; i < config.services.length; i++) {
|
||||
if (config.services[i] === service) {
|
||||
config.services.splice(i, 1);
|
||||
}
|
||||
}
|
||||
config.modules = _.unique(config.modules);
|
||||
config.modules.sort(function(a, b) {
|
||||
config.services = _.unique(config.services);
|
||||
config.services.sort(function(a, b) {
|
||||
return a > b;
|
||||
});
|
||||
fs.writeFile(configFilePath, JSON.stringify(config, null, 2), done);
|
||||
|
@ -41,16 +41,16 @@ function removeConfig(configFilePath, module, done) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Will uninstall a Node.js module and remove from package.json.
|
||||
* Will uninstall a Node.js service and remove from package.json.
|
||||
* @param {String} configDir - The absolute configuration directory path
|
||||
* @param {String} module - The name of the module
|
||||
* @param {String} service - The name of the service
|
||||
* @param {Function} done
|
||||
*/
|
||||
function uninstallModule(configDir, module, done) {
|
||||
function uninstallService(configDir, service, done) {
|
||||
$.checkArgument(path.isAbsolute(configDir), 'An absolute path is expected');
|
||||
$.checkArgument(_.isString(module), 'A string is expected for the module argument');
|
||||
$.checkArgument(_.isString(service), 'A string is expected for the service argument');
|
||||
|
||||
var child = spawn('npm', ['uninstall', module, '--save'], {cwd: configDir});
|
||||
var child = spawn('npm', ['uninstall', service, '--save'], {cwd: configDir});
|
||||
|
||||
child.stdout.on('data', function(data) {
|
||||
process.stdout.write(data);
|
||||
|
@ -62,7 +62,7 @@ function uninstallModule(configDir, module, done) {
|
|||
|
||||
child.on('close', function(code) {
|
||||
if (code !== 0) {
|
||||
return done(new Error('There was an error uninstalling module: ' + module));
|
||||
return done(new Error('There was an error uninstalling service(s): ' + service));
|
||||
} else {
|
||||
return done();
|
||||
}
|
||||
|
@ -70,26 +70,26 @@ function uninstallModule(configDir, module, done) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Will remove a Node.js module if it is installed.
|
||||
* Will remove a Node.js service if it is installed.
|
||||
* @param {String} configDir - The absolute configuration directory path
|
||||
* @param {String} module - The name of the module
|
||||
* @param {String} service - The name of the service
|
||||
* @param {Function} done
|
||||
*/
|
||||
function removeModule(configDir, module, done) {
|
||||
function removeService(configDir, service, done) {
|
||||
$.checkArgument(path.isAbsolute(configDir), 'An absolute path is expected');
|
||||
$.checkArgument(_.isString(module), 'A string is expected for the module argument');
|
||||
$.checkArgument(_.isString(service), 'A string is expected for the service argument');
|
||||
|
||||
// check if the module is installed
|
||||
// check if the service is installed
|
||||
npm.load(function(err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
npm.commands.ls([module], true /*silent*/, function(err, data, lite) {
|
||||
npm.commands.ls([service], true /*silent*/, function(err, data, lite) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
if (lite.dependencies) {
|
||||
uninstallModule(configDir, module, done);
|
||||
uninstallService(configDir, service, done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
|
@ -99,10 +99,10 @@ function removeModule(configDir, module, done) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Will remove the Node.js module and from the bitcore-node configuration.
|
||||
* Will remove the Node.js service and from the bitcore-node configuration.
|
||||
* @param {String} options.cwd - The current working directory
|
||||
* @param {String} options.dirname - The bitcore-node configuration directory
|
||||
* @param {Array} options.modules - An array of strings of module names
|
||||
* @param {Array} options.services - An array of strings of service names
|
||||
* @param {Function} done - A callback function called when finished
|
||||
*/
|
||||
function remove(options, done) {
|
||||
|
@ -112,10 +112,10 @@ function remove(options, done) {
|
|||
_.isString(options.path) && path.isAbsolute(options.path),
|
||||
'An absolute path is expected'
|
||||
);
|
||||
$.checkArgument(Array.isArray(options.modules));
|
||||
$.checkArgument(Array.isArray(options.services));
|
||||
|
||||
var configPath = options.path;
|
||||
var modules = options.modules;
|
||||
var services = options.services;
|
||||
|
||||
var bitcoreConfigPath = path.resolve(configPath, 'bitcore-node.json');
|
||||
var packagePath = path.resolve(configPath, 'package.json');
|
||||
|
@ -127,15 +127,15 @@ function remove(options, done) {
|
|||
}
|
||||
|
||||
async.eachSeries(
|
||||
modules,
|
||||
function(module, next) {
|
||||
// if the module is installed remove it
|
||||
removeModule(configPath, module, function(err) {
|
||||
services,
|
||||
function(service, next) {
|
||||
// if the service is installed remove it
|
||||
removeService(configPath, service, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
// remove module to bitcore-node.json
|
||||
removeConfig(bitcoreConfigPath, module, next);
|
||||
// remove service to bitcore-node.json
|
||||
removeConfig(bitcoreConfigPath, service, next);
|
||||
});
|
||||
}, done
|
||||
);
|
||||
|
|
|
@ -20,11 +20,15 @@ log.debug = function() {};
|
|||
* }
|
||||
* ]
|
||||
* @param {Function} req - The require function to use
|
||||
* @param {Array} cwd - The local path (for requiring services)
|
||||
* @param {Object} config
|
||||
* @param {Array} config.services - An array of strings of service names.
|
||||
* @returns {Array}
|
||||
*/
|
||||
function setupServices(req, config) {
|
||||
function setupServices(req, cwd, config) {
|
||||
|
||||
module.paths.push(path.resolve(cwd, './node_modules'));
|
||||
|
||||
var services = [];
|
||||
if (config.services) {
|
||||
for (var i = 0; i < config.services.length; i++) {
|
||||
|
@ -160,7 +164,7 @@ function registerExitHandlers(proc, node) {
|
|||
function start(options) {
|
||||
|
||||
var fullConfig = _.clone(options.config);
|
||||
fullConfig.services = setupServices(require, options.config);
|
||||
fullConfig.services = setupServices(require, options.path, options.config);
|
||||
fullConfig.datadir = path.resolve(options.path, options.config.datadir);
|
||||
|
||||
var node = new BitcoreNode(fullConfig);
|
||||
|
|
|
@ -47,14 +47,14 @@
|
|||
"async": "^1.3.0",
|
||||
"bindings": "^1.2.1",
|
||||
"bitcore": "^0.13.0",
|
||||
"colors": "^1.1.2",
|
||||
"body-parser": "^1.13.3",
|
||||
"colors": "^1.1.2",
|
||||
"commander": "^2.8.1",
|
||||
"errno": "^0.1.4",
|
||||
"express": "^4.13.3",
|
||||
"leveldown": "^1.4.1",
|
||||
"levelup": "^1.2.1",
|
||||
"liftoff": "^2.1.0",
|
||||
"express": "^4.13.3",
|
||||
"memdown": "^1.0.0",
|
||||
"mkdirp": "0.5.0",
|
||||
"nan": "1.3.0",
|
||||
|
|
|
@ -15,7 +15,7 @@ describe('#remove', function() {
|
|||
var testDir = path.resolve(basePath, 'temporary-test-data');
|
||||
var startConfig = {
|
||||
name: 'My Node',
|
||||
modules: ['a', 'b', 'c']
|
||||
services: ['a', 'b', 'c']
|
||||
};
|
||||
var startPackage = {};
|
||||
|
||||
|
@ -56,7 +56,7 @@ describe('#remove', function() {
|
|||
it('will give an error if expected files do not exist', function(done) {
|
||||
remove({
|
||||
path: path.resolve(testDir, 's0'),
|
||||
modules: ['b']
|
||||
services: ['b']
|
||||
}, function(err) {
|
||||
should.exist(err);
|
||||
err.message.match(/^Invalid state/);
|
||||
|
@ -64,7 +64,7 @@ describe('#remove', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('will update bitcore-node.json modules', function(done) {
|
||||
it('will update bitcore-node.json services', function(done) {
|
||||
var spawn = sinon.stub().returns({
|
||||
stdout: {
|
||||
on: sinon.stub()
|
||||
|
@ -89,12 +89,12 @@ describe('#remove', function() {
|
|||
});
|
||||
removetest({
|
||||
path: path.resolve(testDir, 's0/s1/'),
|
||||
modules: ['b']
|
||||
services: ['b']
|
||||
}, function(err) {
|
||||
should.not.exist(err);
|
||||
var configPath = path.resolve(testDir, 's0/s1/bitcore-node.json');
|
||||
var config = JSON.parse(fs.readFileSync(configPath));
|
||||
config.modules.should.deep.equal(['a', 'c']);
|
||||
config.services.should.deep.equal(['a', 'c']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -125,10 +125,10 @@ describe('#remove', function() {
|
|||
|
||||
removetest({
|
||||
path: path.resolve(testDir, 's0/s1/'),
|
||||
modules: ['b']
|
||||
services: ['b']
|
||||
}, function(err) {
|
||||
should.exist(err);
|
||||
err.message.should.equal('There was an error uninstalling module: b');
|
||||
err.message.should.equal('There was an error uninstalling service(s): b');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ var start = require('../../lib/scaffold/start');
|
|||
|
||||
describe('#start', function() {
|
||||
describe('#setupServices', function() {
|
||||
var cwd = process.cwd();
|
||||
var setupServices = proxyquire('../../lib/scaffold/start', {}).setupServices;
|
||||
it('will require an internal module', function() {
|
||||
function InternalService() {}
|
||||
|
@ -28,7 +29,7 @@ describe('#start', function() {
|
|||
}
|
||||
}
|
||||
};
|
||||
var services = setupServices(testRequire, config);
|
||||
var services = setupServices(testRequire, cwd, config);
|
||||
services[0].name.should.equal('internal');
|
||||
services[0].config.should.deep.equal({param: 'value'});
|
||||
services[0].module.should.equal(InternalService);
|
||||
|
@ -53,7 +54,7 @@ describe('#start', function() {
|
|||
var config = {
|
||||
services: ['local']
|
||||
};
|
||||
var services = setupServices(testRequire, config);
|
||||
var services = setupServices(testRequire, cwd, config);
|
||||
services[0].name.should.equal('local');
|
||||
services[0].module.should.equal(LocalService);
|
||||
});
|
||||
|
@ -78,7 +79,7 @@ describe('#start', function() {
|
|||
var config = {
|
||||
services: ['local']
|
||||
};
|
||||
var services = setupServices(testRequire, config);
|
||||
var services = setupServices(testRequire, cwd, config);
|
||||
services[0].name.should.equal('local');
|
||||
services[0].module.should.equal(LocalService);
|
||||
});
|
||||
|
@ -91,7 +92,7 @@ describe('#start', function() {
|
|||
services: ['bitcoind']
|
||||
};
|
||||
(function() {
|
||||
setupServices(testRequire, config);
|
||||
setupServices(testRequire, cwd, config);
|
||||
}).should.throw('Could not load service');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue