Applied changes requested in pull review

This commit is contained in:
Jim Unger 2015-07-13 12:12:49 -05:00
parent 6a5978145d
commit 7a37dcf71d
11 changed files with 123 additions and 548 deletions

View file

@ -9,7 +9,6 @@ set NODE=%DIR%\node\node.exe
set SERVER=%DIR%\src\bin\kibana.js
set NODE_ENV="production"
set CONFIG_PATH=%DIR%\config\kibana.yml
set NPM=npm
TITLE Kibana Server @@version

View file

@ -1,10 +1,10 @@
#!/usr/bin/env node
var program = require('commander');
require('../lib/commanderExtensions.js')(program);
require('../lib/commanderExtensions')(program);
var path = require('path');
var startupOptions = require('./startup/startupOptions.js');
var startup = require('./startup/startup.js');
var startupOptions = require('./startup/startupOptions');
var startup = require('./startup/startup');
var pluginProgram = require('./plugin/plugin');
var env = (process.env.NODE_ENV) ? process.env.NODE_ENV : 'development';

View file

@ -16,8 +16,7 @@ module.exports = function (dest, logger) {
return reject(new Error('Plugin does not contain package.json file'));
}
var cmd = (process.env.NPM) ? process.env.NPM : 'npm';
cmd += ' install';
var cmd = '"' + path.resolve(path.dirname(process.execPath), 'npm').replace(/\\/g, '/') + '" install --production';
var child = exec(cmd, { cwd: dest });
child.on('error', function (err) {
@ -27,7 +26,7 @@ module.exports = function (dest, logger) {
if (code === 0) {
resolve();
} else {
reject(new Error('npm install failed.'));
reject(new Error('npm install failed with code ' + code));
}
});

View file

@ -24,10 +24,26 @@ module.exports = function (program) {
}
}
var installDesc =
'The plugin to install\n\n' +
'\tCommon examples:\n' +
'\t -i username/sample\n' +
'\t attempts to download the latest version from the following urls:\n' +
'\t https://download.elastic.co/username/sample/sample-latest.tar.gz\n' +
'\t https://github.com/username/sample/archive/master.tar.gz\n\n' +
'\t -i username/sample/v1.1.1\n' +
'\t attempts to download from the following urls:\n' +
'\t https://download.elastic.co/username/sample/sample-v1.1.1.tar.gz\n' +
'\t https://github.com/username/sample/archive/v1.1.1.tar.gz\n\n' +
'\t -i sample -u http://www.example.com/other_name.tar.gz\n' +
'\t attempts to download from the specified url,\n' +
'\t and installs the plugin found at that url as "sample"' +
'\n';
program
.command('plugin')
.description('Maintain Plugins')
.option('-i, --install <org>/<plugin>/<version>', 'The plugin to install')
.option('-i, --install <org>/<plugin>/<version>', installDesc)
.option('-r, --remove <plugin>', 'The plugin to remove')
.option('-s, --silent', 'Disable process messaging')
.option('-u, --url <url>', 'Specify download url')

View file

@ -3,7 +3,7 @@ var zlib = require('zlib');
var Promise = require('bluebird');
var request = require('request');
var tar = require('tar');
var progressReporter = require('./progressReporter.js');
var progressReporter = require('./progressReporter');
module.exports = function (settings, logger) {

View file

@ -1,6 +1,6 @@
var pluginDownloader = require('./pluginDownloader.js');
var pluginCleaner = require('./pluginCleaner.js');
var npmInstall = require('./npmInstall.js');
var pluginDownloader = require('./pluginDownloader');
var pluginCleaner = require('./pluginCleaner');
var npmInstall = require('./npmInstall');
var fs = require('fs');
module.exports = {
@ -35,8 +35,7 @@ function install(settings, logger) {
logger.log('Plugin installation complete!');
})
.catch(function (e) {
logger.error('Plugin installation was unsuccessful.');
logger.error(e.message);
logger.error('Plugin installation was unsuccessful due to error "' + e.message + '"');
cleaner.cleanError();
process.exit(70);
});

View file

@ -15,12 +15,14 @@
return;
}
if (!sameLine) data += '\n';
process.stdout.write(data);
if (!sameLine) process.stdout.write('\n');
previousLineEnded = !sameLine;
}
function error(data) {
if (silent) return;
if (!previousLineEnded) {
process.stderr.write('\n');
}

View file

@ -18,8 +18,9 @@ function remove(settings, logger) {
logger.log('Removing ' + settings.package + '...');
rimraf.sync(settings.pluginPath);
} catch (ex) {
logger.error(ex.message);
} catch (err) {
var message = 'Unable to remove plugin "' + settings.package + '" because of error: "' + err.message + '"';
logger.error(message);
process.exit(74);
}
}

View file

@ -12,52 +12,43 @@ describe('kibana cli', function () {
describe('settings.action', function () {
var program = {
command: function () { return program; },
description: function () { return program; },
option: function () { return program; },
action: function (processCommand) {
processCommand();
}
};
function testUsageOfAction(action) {
describe('when action is ' + action, function () {
before(function () {
var program = {
command: function () { return program; },
description: function () { return program; },
option: function () { return program; },
action: function (processCommand) {
processCommand();
}
};
beforeEach(function () {
sinon.stub(remover, 'remove');
sinon.stub(installer, 'install');
});
sinon.stub(remover, 'remove');
sinon.stub(installer, 'install');
afterEach(function () {
remover.remove.restore();
installer.install.restore();
settingParser.parse.restore();
});
sinon
.stub(settingParser, 'parse')
.returns({ action: action });
it('should call remove if settings.action is "remove"', function () {
sinon.stub(settingParser, 'parse', function () {
return {
action: 'remove'
};
plugin(program);
});
it('calls the right function', function () {
expect(remover.remove.called).to.be(action === 'remove');
expect(installer.install.called).to.be(action === 'install');
});
after(function () {
remover.remove.restore();
installer.install.restore();
settingParser.parse.restore();
});
});
}
plugin(program);
expect(remover.remove.called).to.be(true);
expect(installer.install.called).to.be(false);
});
it('should call install if settings.action is "install"', function () {
sinon.stub(settingParser, 'parse', function () {
return {
action: 'install'
};
});
plugin(program);
expect(remover.remove.called).to.be(false);
expect(installer.install.called).to.be(true);
});
testUsageOfAction('remove');
testUsageOfAction('install');
});
describe('commander options', function () {

View file

@ -26,7 +26,10 @@ describe('kibana cli', function () {
var message = 'this is my message';
logger.log(message);
expect(process.stdout.write.calledWith(message + '\n')).to.be(true);
var callCount = process.stdout.write.callCount;
expect(process.stdout.write.getCall(callCount - 2).args[0]).to.be(message);
expect(process.stdout.write.getCall(callCount - 1).args[0]).to.be('\n');
});
it('should log messages to the console and append not append a new line', function () {
@ -35,7 +38,7 @@ describe('kibana cli', function () {
}
logger.log('Done!');
expect(process.stdout.write.callCount).to.be(12);
expect(process.stdout.write.callCount).to.be(13);
expect(process.stdout.write.getCall(0).args[0]).to.be('.');
expect(process.stdout.write.getCall(1).args[0]).to.be('.');
expect(process.stdout.write.getCall(2).args[0]).to.be('.');
@ -47,7 +50,8 @@ describe('kibana cli', function () {
expect(process.stdout.write.getCall(8).args[0]).to.be('.');
expect(process.stdout.write.getCall(9).args[0]).to.be('.');
expect(process.stdout.write.getCall(10).args[0]).to.be('\n');
expect(process.stdout.write.getCall(11).args[0]).to.be('Done!\n');
expect(process.stdout.write.getCall(11).args[0]).to.be('Done!');
expect(process.stdout.write.getCall(12).args[0]).to.be('\n');
});
it('should not log any messages when silent is set', function () {
@ -84,13 +88,13 @@ describe('kibana cli', function () {
expect(process.stderr.write.calledWith(message + '\n')).to.be(true);
});
it('should log error messages to the console regardless of silent setting', function () {
it('should not log any error messages when silent is set', function () {
logger = pluginLogger(true);
var message = 'this is my error';
logger.error(message);
expect(process.stderr.write.calledWith(message + '\n')).to.be(true);
expect(process.stderr.write.callCount).to.be(0);
});
});

View file

@ -33,505 +33,69 @@ describe('kibana cli', function () {
describe('bad response codes', function () {
it('should set the state to error for response code = 400', function () {
progress.handleResponse({ statusCode: 400 });
function testErrorResponse(element, index, array) {
it('should set the state to error for response code = ' + element, function () {
progress.handleResponse({ statusCode: element });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
});
}
it('should set the state to error for response code = 401', function () {
progress.handleResponse({ statusCode: 401 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 402', function () {
progress.handleResponse({ statusCode: 402 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 403', function () {
progress.handleResponse({ statusCode: 403 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 404', function () {
progress.handleResponse({ statusCode: 404 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 405', function () {
progress.handleResponse({ statusCode: 405 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 406', function () {
progress.handleResponse({ statusCode: 406 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 407', function () {
progress.handleResponse({ statusCode: 407 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 408', function () {
progress.handleResponse({ statusCode: 408 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 409', function () {
progress.handleResponse({ statusCode: 409 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 410', function () {
progress.handleResponse({ statusCode: 410 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 411', function () {
progress.handleResponse({ statusCode: 411 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 412', function () {
progress.handleResponse({ statusCode: 412 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 413', function () {
progress.handleResponse({ statusCode: 413 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 414', function () {
progress.handleResponse({ statusCode: 414 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 415', function () {
progress.handleResponse({ statusCode: 415 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 416', function () {
progress.handleResponse({ statusCode: 416 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 417', function () {
progress.handleResponse({ statusCode: 417 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 500', function () {
progress.handleResponse({ statusCode: 500 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 501', function () {
progress.handleResponse({ statusCode: 501 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 502', function () {
progress.handleResponse({ statusCode: 502 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 503', function () {
progress.handleResponse({ statusCode: 503 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 504', function () {
progress.handleResponse({ statusCode: 504 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
it('should set the state to error for response code = 505', function () {
progress.handleResponse({ statusCode: 505 });
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(true);
expect(errorStub.lastCall.args[0].message).to.match(/ENOTFOUND/);
});
});
var badCodes = [
'400', '401', '402', '403', '404', '405', '406', '407', '408', '409', '410',
'411', '412', '413', '414', '415', '416', '417', '500', '501', '502', '503',
'504', '505'
];
badCodes.forEach(testErrorResponse);
});
describe('good response codes', function () {
it('should set the state to error for response code = 200', function () {
progress.handleResponse({ statusCode: 200, headers: { 'content-length': 1000 } });
progress.handleEnd();
function testSuccessResponse(statusCode, index, array) {
it('should set the state to success for response code = ' + statusCode, function () {
progress.handleResponse({ statusCode: statusCode, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
});
}
it('should set the state to error for response code = 201', function () {
progress.handleResponse({ statusCode: 201, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
function testUnknownNumber(statusCode, index, array) {
it('should log "unknown number of" for response code = ' + statusCode + ' without content-length header', function () {
progress.handleResponse({ statusCode: statusCode, headers: {} });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/unknown number/);
});
});
});
}
it('should set the state to error for response code = 202', function () {
progress.handleResponse({ statusCode: 202, headers: { 'content-length': 1000 } });
progress.handleEnd();
var goodCodes = [
'200', '201', '202', '203', '204', '205', '206', '300', '301', '302', '303',
'304', '305', '306', '307'
];
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 203', function () {
progress.handleResponse({ statusCode: 203, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 204', function () {
progress.handleResponse({ statusCode: 204, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 205', function () {
progress.handleResponse({ statusCode: 205, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 206', function () {
progress.handleResponse({ statusCode: 206, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 300', function () {
progress.handleResponse({ statusCode: 300, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 301', function () {
progress.handleResponse({ statusCode: 301, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 302', function () {
progress.handleResponse({ statusCode: 302, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 303', function () {
progress.handleResponse({ statusCode: 303, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 304', function () {
progress.handleResponse({ statusCode: 304, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 305', function () {
progress.handleResponse({ statusCode: 305, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 306', function () {
progress.handleResponse({ statusCode: 306, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should set the state to error for response code = 307', function () {
progress.handleResponse({ statusCode: 307, headers: { 'content-length': 1000 } });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/1000/);
});
});
it('should log "unknown number of" for response codes < 400 without content-length header', function () {
progress.handleResponse({ statusCode: 200, headers: {} });
progress.handleEnd();
var errorStub = sinon.stub();
return progress.promise
.catch(errorStub)
.then(function (data) {
expect(errorStub.called).to.be(false);
expect(logger.log.getCall(logger.log.callCount - 2).args[0]).to.match(/unknown number/);
});
});
goodCodes.forEach(testSuccessResponse);
goodCodes.forEach(testUnknownNumber);
});