diff --git a/lib/cli/bitcore.js b/lib/cli/bitcore.js index df3ea894..963d3b24 100644 --- a/lib/cli/bitcore.js +++ b/lib/cli/bitcore.js @@ -2,7 +2,7 @@ var Liftoff = require('liftoff'); -function main() { +function main(parentServicesPath, additionalServices) { var liftoff = new Liftoff({ name: 'bitcore', @@ -23,16 +23,14 @@ function main() { }, function(env){ var node; - if (env.modulePackage && env.configPath) { - // use the configured version - node = require(env.modulePath); + if (typeof env.modulePath === 'undefined') { + node = require('../../'); + node.cli.main(parentServicesPath, additionalServices); } else { - // use this version - node = require('..'); + node = require(env.modulePath); + node.cli.main(); } - node.cli.main(); - }); } diff --git a/lib/cli/bitcored.js b/lib/cli/bitcored.js index 277e4f0a..731311f7 100644 --- a/lib/cli/bitcored.js +++ b/lib/cli/bitcored.js @@ -2,7 +2,7 @@ var Liftoff = require('liftoff'); -function main() { +function main(parentServicesPath, additionalServices) { var liftoff = new Liftoff({ name: 'bitcored', @@ -23,15 +23,14 @@ function main() { }, function(env){ var node; - if (env.modulePackage && env.configPath) { - // use the configured version - node = require(env.modulePath); - } else { - // use this version - node = require('..'); - } - node.cli.daemon(); + if (typeof env.modulePath === 'undefined') { + node = require('../../'); + node.cli.daemon(parentServicesPath, additionalServices); + } else { + node = require(env.modulePath); + node.cli.daemon(); + } }); diff --git a/lib/cli/daemon.js b/lib/cli/daemon.js index cd12c547..959b3135 100644 --- a/lib/cli/daemon.js +++ b/lib/cli/daemon.js @@ -4,7 +4,7 @@ var program = require('commander'); var path = require('path'); var bitcore = require('..'); -function main() { +function main(servicesPath, additionalServices) { /* jshint maxstatements: 100 */ var version = bitcore.version; @@ -25,11 +25,16 @@ function main() { } var configInfo = findConfig(program.config || process.cwd()); if (!configInfo) { - configInfo = defaultConfig(); + configInfo = defaultConfig({ + additionalServices: additionalServices + }); } if(program.daemon) { configInfo.config.daemon = true; } + if (servicesPath) { + configInfo.servicesPath = servicesPath; + } start(configInfo); } diff --git a/lib/cli/main.js b/lib/cli/main.js index ce49f453..07a92671 100644 --- a/lib/cli/main.js +++ b/lib/cli/main.js @@ -4,7 +4,7 @@ var program = require('commander'); var path = require('path'); var bitcorenode = require('..'); -function main() { +function main(servicesPath, additionalServices) { /* jshint maxstatements: 100 */ var version = bitcorenode.version; @@ -52,11 +52,16 @@ function main() { } var configInfo = findConfig(cmd.config || process.cwd()); if (!configInfo) { - configInfo = defaultConfig(); + configInfo = defaultConfig({ + additionalServices: additionalServices + }); } if(cmd.daemon) { configInfo.config.daemon = true; } + if (servicesPath) { + configInfo.servicesPath = servicesPath; + } start(configInfo); }); diff --git a/lib/scaffold/create.js b/lib/scaffold/create.js index 35f41a41..41f1f2b7 100644 --- a/lib/scaffold/create.js +++ b/lib/scaffold/create.js @@ -9,7 +9,7 @@ var path = require('path'); var packageFile = require('../../package.json'); var mkdirp = require('mkdirp'); var fs = require('fs'); -var defaultConfig = require('./default-config'); +var defaultBaseConfig = require('./default-base-config'); var version; if (packageFile.version.match('-dev')) { @@ -55,7 +55,7 @@ function createConfigDirectory(configDir, datadir, isGlobal, done) { throw err; } - var configInfo = defaultConfig(); + var configInfo = defaultBaseConfig(); var config = configInfo.config; config.datadir = datadir; diff --git a/lib/scaffold/default-base-config.js b/lib/scaffold/default-base-config.js new file mode 100644 index 00000000..e8b66696 --- /dev/null +++ b/lib/scaffold/default-base-config.js @@ -0,0 +1,21 @@ +'use strict'; + +var path = require('path'); + +/** + * Will return the path and default bitcore-node configuration on environment variables + * or default locations. + */ +function getDefaultBaseConfig() { + return { + path: process.cwd(), + config: { + datadir: path.resolve(process.env.HOME, '.bitcoin'), + network: 'livenet', + port: 3001, + services: ['bitcoind', 'db', 'address', 'web'] + } + }; +} + +module.exports = getDefaultBaseConfig; diff --git a/lib/scaffold/default-config.js b/lib/scaffold/default-config.js index 843688f3..83d36f7a 100644 --- a/lib/scaffold/default-config.js +++ b/lib/scaffold/default-config.js @@ -1,21 +1,57 @@ 'use strict'; var path = require('path'); +var mkdirp = require('mkdirp'); +var fs = require('fs'); /** - * Will return the path and default bitcore-node configuration on environment variables - * or default locations. + * Will return the path and default bitcore-node configuration. It will search for the + * configuration file in the "~/.bitcore" directory, and if it doesn't exist, it will create one + * based on default settings. + * @param {Object} [options] + * @param {Array} [options.additionalServices] - An optional array of services. */ -function getDefaultConfig() { +function getDefaultConfig(options) { + /* jshint maxstatements: 40 */ + if (!options) { + options = {}; + } + + var defaultPath = path.resolve(process.env.HOME, './.bitcore'); + var defaultConfigFile = path.resolve(defaultPath, './bitcore-node.json'); + + if (!fs.existsSync(defaultPath)) { + mkdirp.sync(defaultPath); + } + + var defaultServices = ['bitcoind', 'db', 'address', 'web']; + if (options.additionalServices) { + defaultServices = defaultServices.concat(options.additionalServices); + } + + if (!fs.existsSync(defaultConfigFile)) { + var defaultConfig = { + datadir: path.resolve(defaultPath, './data'), + network: 'livenet', + port: 3001, + services: defaultServices + }; + fs.writeFileSync(defaultConfigFile, JSON.stringify(defaultConfig, null, 2)); + } + + var defaultDataDir = path.resolve(defaultPath, './data'); + + if (!fs.existsSync(defaultDataDir)) { + mkdirp.sync(defaultDataDir); + } + + var config = JSON.parse(fs.readFileSync(defaultConfigFile, 'utf-8')); + return { - path: process.cwd(), - config: { - datadir: process.env.BITCORENODE_DIR || path.resolve(process.env.HOME, '.bitcoin'), - network: process.env.BITCORENODE_NETWORK || 'livenet', - port: Number(process.env.BITCORENODE_PORT) || 3001, - services: ['bitcoind', 'db', 'address', 'web'] - } + path: defaultPath, + config: config }; + } module.exports = getDefaultConfig; diff --git a/lib/scaffold/start.js b/lib/scaffold/start.js index 9949347b..f9ac430a 100644 --- a/lib/scaffold/start.js +++ b/lib/scaffold/start.js @@ -24,14 +24,14 @@ log.debug = function() {}; * } * ] * @param {Function} req - The require function to use - * @param {Array} cwd - The local path (for requiring services) + * @param {Array} servicesPath - 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, cwd, config) { +function setupServices(req, servicesPath, config) { - module.paths.push(path.resolve(cwd, './node_modules')); + module.paths.push(path.resolve(servicesPath, './node_modules')); var services = []; if (config.services) { @@ -180,6 +180,7 @@ function exitHandler(options, _process, node, err) { * This function will instantiate and start a Node, requiring the necessary service * modules, and registering event handlers. * @param {Object} options + * @param {Object} options.servicesPath - The path to the location of service modules * @param {String} options.path - The absolute path of the configuration file * @param {Object} options.config - The parsed bitcore-node.json configuration file * @param {Array} options.config.services - An array of services names. @@ -191,7 +192,15 @@ function exitHandler(options, _process, node, err) { function start(options) { var fullConfig = _.clone(options.config); - fullConfig.services = start.setupServices(require, options.path, options.config); + + var servicesPath; + if (options.servicesPath) { + servicesPath = options.servicesPath; // services are in a different directory than the config + } else { + servicesPath = options.path; // defaults to the same directory + } + + fullConfig.services = start.setupServices(require, servicesPath, options.config); fullConfig.datadir = path.resolve(options.path, options.config.datadir); if (fullConfig.daemon) { diff --git a/test/scaffold/create.integration.js b/test/scaffold/create.integration.js index 10378806..f2c61523 100644 --- a/test/scaffold/create.integration.js +++ b/test/scaffold/create.integration.js @@ -53,10 +53,6 @@ describe('#create', function() { }); it('will create scaffold files', function() { - delete process.env.BITCORENODE_DIR; - delete process.env.BITCORENODE_NETWORK; - delete process.env.BITCORENODE_PORT; - create({ cwd: testDir, dirname: 'mynode', diff --git a/test/scaffold/default-base-config.integration.js b/test/scaffold/default-base-config.integration.js new file mode 100644 index 00000000..8b23a9fa --- /dev/null +++ b/test/scaffold/default-base-config.integration.js @@ -0,0 +1,17 @@ +'use strict'; + +var should = require('chai').should(); +var defaultBaseConfig = require('../../lib/scaffold/default-base-config'); + +describe('#defaultConfig', function() { + it('will return expected configuration', function() { + var cwd = process.cwd(); + var home = process.env.HOME; + var info = defaultBaseConfig(); + info.path.should.equal(cwd); + info.config.datadir.should.equal(home + '/.bitcoin'); + info.config.network.should.equal('livenet'); + info.config.port.should.equal(3001); + info.config.services.should.deep.equal(['bitcoind', 'db', 'address', 'web']); + }); +}); diff --git a/test/scaffold/default-config.integration.js b/test/scaffold/default-config.integration.js index 23f9c598..cbe00816 100644 --- a/test/scaffold/default-config.integration.js +++ b/test/scaffold/default-config.integration.js @@ -1,35 +1,90 @@ 'use strict'; var should = require('chai').should(); -var defaultConfig = require('../../lib/scaffold/default-config'); +var sinon = require('sinon'); +var proxyquire = require('proxyquire'); describe('#defaultConfig', function() { - it('will return expected configuration', function() { + var config = JSON.stringify({ + datadir: process.env.HOME + '/.bitcore/data', + network: 'livenet', + port: 3001, + services: [ + 'bitcoind', + 'db', + 'address', + 'web' + ] + }, null, 2); + var defaultConfig = proxyquire('../../lib/scaffold/default-config', { + fs: { + existsSync: sinon.stub().returns(false), + writeFileSync: function(path, data) { + path.should.equal(process.env.HOME + '/.bitcore/bitcore-node.json'); + data.should.equal(config); + }, + readFileSync: function() { + return config; + } + }, + mkdirp: { + sync: sinon.stub() + } + }); var cwd = process.cwd(); - delete process.env.BITCORENODE_DIR; - delete process.env.BITCORENODE_NETWORK; - delete process.env.BITCORENODE_PORT; var home = process.env.HOME; var info = defaultConfig(); - info.path.should.equal(cwd); - info.config.datadir.should.equal(home + '/.bitcoin'); + info.path.should.equal(home + '/.bitcore'); + info.config.datadir.should.equal(home + '/.bitcore/data'); info.config.network.should.equal('livenet'); info.config.port.should.equal(3001); info.config.services.should.deep.equal(['bitcoind', 'db', 'address', 'web']); }); - - it('will return expected configuration from environment variables', function() { - var cwd = process.cwd(); - process.env.BITCORENODE_DIR = '/home/bitcore-node/.bitcoin'; - process.env.BITCORENODE_NETWORK = 'testnet'; - process.env.BITCORENODE_PORT = 3002; - var info = defaultConfig(); - info.path.should.equal(cwd); - info.config.datadir.should.equal('/home/bitcore-node/.bitcoin'); - info.config.network.should.equal('testnet'); - info.config.port.should.equal(3002); - info.config.services.should.deep.equal(['bitcoind', 'db', 'address', 'web']); + it('will include additional services', function() { + var config = JSON.stringify({ + datadir: process.env.HOME + '/.bitcore/data', + network: 'livenet', + port: 3001, + services: [ + 'bitcoind', + 'db', + 'address', + 'web', + 'insight-api', + 'insight-ui' + ] + }, null, 2); + var defaultConfig = proxyquire('../../lib/scaffold/default-config', { + fs: { + existsSync: sinon.stub().returns(false), + writeFileSync: function(path, data) { + path.should.equal(process.env.HOME + '/.bitcore/bitcore-node.json'); + data.should.equal(config); + }, + readFileSync: function() { + return config; + } + }, + mkdirp: { + sync: sinon.stub() + } + }); + var home = process.env.HOME; + var info = defaultConfig({ + additionalServices: ['insight-api', 'insight-ui'] + }); + info.path.should.equal(home + '/.bitcore'); + info.config.datadir.should.equal(home + '/.bitcore/data'); + info.config.network.should.equal('livenet'); + info.config.port.should.equal(3001); + info.config.services.should.deep.equal([ + 'bitcoind', + 'db', + 'address', + 'web', + 'insight-api', + 'insight-ui' + ]); }); - });