CLI Fixes

- Globally installed cli script will load local version
- Modules can add a "bitcoreNode" to package.json to specify a specific module to load
This commit is contained in:
Braydon Fuller 2015-08-25 18:01:54 -04:00
parent 5f9f344edd
commit da537b293b
5 changed files with 159 additions and 83 deletions

View File

@ -2,84 +2,43 @@
'use strict';
var program = require('commander');
var version = require(__dirname + '/../package.json').version;
var bitcore = require('bitcore');
var $ = bitcore.util.preconditions;
var path = require('path');
var create = require('../lib/scaffold/create');
var add = require('../lib/scaffold/add');
var start = require('../lib/scaffold/start');
var findConfig = require('../lib/scaffold/find-config');
var defaultConfig = require('../lib/scaffold/default-config');
var semver = require('semver');
var Liftoff = require('liftoff');
var cliPackage = require('../package.json');
program
.version(version);
program
.command('create <directory> [name]')
.description('Create a new node')
.option('-d, --datadir <dir>', 'Specify the bitcoin database directory')
.action(function(dirname, name, cmd){
if (cmd.datadir) {
cmd.datadir = path.resolve(process.cwd(), cmd.datadir);
}
var opts = {
cwd: process.cwd(),
dirname: dirname,
name: name,
datadir: cmd.datadir || './data',
isGlobal: false
};
create(opts, function(err) {
if (err) {
throw err;
}
console.log('Successfully created node in directory: ', dirname);
});
var liftoff = new Liftoff({
name: 'bitcore-node',
moduleName: 'bitcore-node',
configName: 'bitcore-node',
processTitle: 'bitcore-node'
}).on('require', function (name, module) {
console.log('Loading:', name);
}).on('requireFail', function (name, err) {
console.log('Unable to load:', name, err);
}).on('respawn', function (flags, child) {
console.log('Detected node flags:', flags);
console.log('Respawned to PID:', child.pid);
});
program
.command('start')
.description('Start the current node')
.option('-c, --config <dir>', 'Specify the directory with Bitcore Node configuration')
.action(function(cmd){
if (cmd.config) {
cmd.config = path.resolve(process.cwd(), cmd.config);
}
var configInfo = findConfig(cmd.config || process.cwd());
if (!configInfo) {
configInfo = defaultConfig();
}
start(configInfo);
});
liftoff.launch({
cwd: process.cwd()
}, function(env){
program
.command('add <modules...>')
.alias('install')
.description('Install a module for the current node')
.action(function(modules){
var configInfo = findConfig(process.cwd());
if (!configInfo) {
throw new Error('Could not find configuration, see `bitcore-node create --help`');
var bitcorenode;
if (env.modulePackage && env.configPath) {
// use the local version
if (semver.gt(cliPackage.version, env.modulePackage.version)) {
throw new Error(
'Version mismatch, global bitcore-node is ' + cliPackage.version +
' and local bitcore-node is ' + env.modulePackage.version
);
}
var opts = {
path: configInfo.path,
modules: modules
};
add(opts, function() {
console.log('Successfully added modules: ', modules.join(', '));
});
}).on('--help', function() {
console.log(' Examples:');
console.log();
console.log(' $ bitcore-node add wallet-service');
console.log(' $ bitcore-node add insight-api');
console.log();
});
program.parse(process.argv);
if (process.argv.length === 2) {
program.help();
bitcorenode = require(env.modulePath);
} else {
// use the global version
bitcorenode = require('..');
}
bitcorenode.cli.main();
});

90
cli/main.js Normal file
View File

@ -0,0 +1,90 @@
'use strict';
var program = require('commander');
var path = require('path');
var bitcorenode = require('..');
function main() {
// local commands
var version = bitcorenode.version;
var create = bitcorenode.scaffold.create;
var add = bitcorenode.scaffold.add;
var start = bitcorenode.scaffold.start;
var findConfig = bitcorenode.scaffold.findConfig;
var defaultConfig = bitcorenode.scaffold.defaultConfig;
program
.version(version);
program
.command('create <directory> [name]')
.description('Create a new node')
.option('-d, --datadir <dir>', 'Specify the bitcoin database directory')
.action(function(dirname, name, cmd){
if (cmd.datadir) {
cmd.datadir = path.resolve(process.cwd(), cmd.datadir);
}
var opts = {
cwd: process.cwd(),
dirname: dirname,
name: name,
datadir: cmd.datadir || './data',
isGlobal: false
};
create(opts, function(err) {
if (err) {
throw err;
}
console.log('Successfully created node in directory: ', dirname);
});
});
program
.command('start')
.description('Start the current node')
.option('-c, --config <dir>', 'Specify the directory with Bitcore Node configuration')
.action(function(cmd){
if (cmd.config) {
cmd.config = path.resolve(process.cwd(), cmd.config);
}
var configInfo = findConfig(cmd.config || process.cwd());
if (!configInfo) {
configInfo = defaultConfig();
}
start(configInfo);
});
program
.command('add <modules...>')
.alias('install')
.description('Install a module for the current node')
.action(function(modules){
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
};
add(opts, function() {
console.log('Successfully added modules: ', modules.join(', '));
});
}).on('--help', function() {
console.log(' Examples:');
console.log();
console.log(' $ bitcore-node add wallet-service');
console.log(' $ bitcore-node add insight-api');
console.log();
});
program.parse(process.argv);
if (process.argv.length === 2) {
program.help();
}
}
module.exports = main;

View File

@ -13,5 +13,15 @@ module.exports.errors = require('./lib/errors');
module.exports.modules = {};
module.exports.modules.AddressModule = require('./lib/modules/address');
module.exports.scaffold = {};
module.exports.scaffold.create = require('./lib/scaffold/create');
module.exports.scaffold.add = require('./lib/scaffold/add');
module.exports.scaffold.start = require('./lib/scaffold/start');
module.exports.scaffold.findConfig = require('./lib/scaffold/find-config');
module.exports.scaffold.defaultConfig = require('./lib/scaffold/default-config');
module.exports.cli = {};
module.exports.cli.main = require('./cli/main');
module.exports.deps = {};
module.exports.deps.chainlib = require('chainlib');

View File

@ -15,7 +15,7 @@ var interval = false;
function start(options) {
/* jshint maxstatements: 100 */
var modules = [];
var bitcoreModules = [];
var configPath = options.path;
var config = options.config;
@ -23,16 +23,31 @@ function start(options) {
if (config.modules) {
for (var i = 0; i < config.modules.length; i++) {
var moduleName = config.modules[i];
var module;
var bitcoreModule;
try {
// first try in the built-in bitcore-node modules directory
module = require(path.resolve(__dirname, '../modules/' + moduleName));
bitcoreModule = require(path.resolve(__dirname, '../modules/' + moduleName));
} catch(e) {
// then try loading external modules
module = require(moduleName);
// check if the package.json specifies a specific file to use
var modulePackage = require(moduleName + '/package.json');
var bitcoreNodeModule = moduleName;
if (modulePackage.bitcoreNode) {
bitcoreNodeModule = moduleName + '/' + modulePackage.bitcoreNode;
}
bitcoreModule = require(bitcoreNodeModule);
}
modules.push(module);
// check that the module supports expected methods
if (!bitcoreModule.prototype ||
!bitcoreModule.prototype.start ||
!bitcoreModule.prototype.stop) {
throw new Error(
'Could not load module "' + moduleName + '" as it does not support necessary methods.'
);
}
bitcoreModules.push(bitcoreModule);
}
}
@ -46,7 +61,7 @@ function start(options) {
// load the modules
fullConfig.db = {
modules: modules
modules: bitcoreModules
};
var node = new BitcoreNode(fullConfig);

View File

@ -50,9 +50,11 @@
"chainlib": "^0.2.0",
"commander": "^2.8.1",
"errno": "^0.1.2",
"liftoff": "^2.1.0",
"memdown": "^1.0.0",
"mkdirp": "0.5.0",
"nan": "1.3.0",
"semver": "^5.0.1",
"socket.io": "^1.3.6"
},
"devDependencies": {