Restructure bin functionality to application (#971)

* Restructure bin functionality to application

Lets move functionallity from bin inside the application, making it possible to run without bin.
This commit is contained in:
Peter Hedenskog 2016-06-04 20:40:01 +02:00
parent 3565c5a59e
commit 1da1bd2ad7
3 changed files with 78 additions and 68 deletions

View File

@ -1,17 +1,12 @@
#!/usr/bin/env node
/*eslint no-console: 0*/
'use strict';
const cli = require('../lib/support/cli'),
Sitespeed = require('../lib/sitespeed'),
sitespeed = require('../lib/sitespeed'),
Promise = require('bluebird'),
difference = require('lodash.difference'),
logging = require('../lib/support/logging'),
log = require('intel'),
os = require('os'),
packageInfo = require('../package'),
merge = require('lodash.merge'),
loader = require('../lib/support/pluginLoader');
require('longjohn');
@ -20,32 +15,13 @@ Promise.config({
longStackTraces: true
});
function allInArray(sampleArray, referenceArray) {
return difference(sampleArray, referenceArray).length === 0;
}
process.exitCode = 1;
let parsed = cli.parseCommandLine();
logging.configure(parsed.options);
if (log.isEnabledFor(log.CRITICAL)) { // TODO change the threshold to VERBOSE before releasing 4.0
Promise.longStackTraces();
}
log.info('Versions OS: %s sitespeed.io: %s browsertime: %s coach: %s', os.platform() + ' ' + os.release(), packageInfo.version, packageInfo.dependencies.browsertime, packageInfo.dependencies.webcoach);
loader.parsePluginNames(parsed.explicitOptions)
.then((pluginNames) => {
if (allInArray(['browsertime', 'coach'], pluginNames)) {
parsed.options.browsertime = merge({}, parsed.options.browsertime, {coach: true});
}
return loader.loadPlugins(pluginNames);
})
.then((plugins) => {
let sitespeed = new Sitespeed(plugins, parsed.options);
return sitespeed.run()
return sitespeed.run(pluginNames, parsed.options)
.then((errors) => {
if (errors.length > 0) {
throw new Error('Errors while running:\n' + errors.join('\n'));
@ -54,10 +30,8 @@ loader.parsePluginNames(parsed.explicitOptions)
})
.then(() => {
process.exitCode = 0;
log.info('Finished analysing ' + parsed.url);
})
.catch((e) => {
.catch(() => {
process.exitCode = 1;
log.error('Failing: ' + e.message);
})
.finally(() => process.exit());

View File

@ -1,50 +1,85 @@
'use strict';
const Promise = require('bluebird'),
moment = require('moment');
moment = require('moment'),
log = require('intel'),
os = require('os'),
logging = require('../lib/support/logging'),
difference = require('lodash.difference'),
merge = require('lodash.merge'),
packageInfo = require('../package');
const QueueHandler = require('./support/queueHandler'),
StorageManager = require('./support/storageManager'),
loader = require('./support/pluginLoader'),
urlSource = require('./support/url-source');
function hasFunctionFilter(functionName) {
return ((obj) => (typeof obj[functionName] === 'function'));
}
class App {
constructor(plugins, options) {
this.plugins = plugins;
this.options = options;
}
run() {
function runOptionalFunction(objects, fN) {
// NOTE: note slicing due to https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
let args = new Array(arguments.length - 2);
for (let i = 2; i < arguments.length; i++) {
args[i - 2] = arguments[i];
}
return Promise.resolve(objects)
.filter(hasFunctionFilter(fN))
.map((plugin) => Promise.resolve(plugin[fN].apply(plugin, args)));
}
let urlSources = [urlSource];
const plugins = urlSources.concat(this.plugins),
timestamp = moment();
if (this.options.utc) {
timestamp.utc();
}
const storageManager = new StorageManager(this.options, timestamp),
queueHandler = new QueueHandler(this.plugins, this.options);
return runOptionalFunction(plugins, 'open', {storageManager, timestamp}, this.options)
.then(() => queueHandler.run(urlSources))
.tap((errors) => runOptionalFunction(plugins, 'close', this.options, errors));
}
function allInArray(sampleArray, referenceArray) {
return difference(sampleArray, referenceArray).length === 0;
}
module.exports = App;
function runOptionalFunction(objects, fN) {
// NOTE: note slicing due to https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
let args = new Array(arguments.length - 2);
for (let i = 2; i < arguments.length; i++) {
args[i - 2] = arguments[i];
}
return Promise.resolve(objects)
.filter(hasFunctionFilter(fN))
.map((plugin) => Promise.resolve(plugin[fN].apply(plugin, args)));
}
module.exports = {
run(pluginNames, options) {
const timestamp = moment();
if (options.utc) {
timestamp.utc();
}
const storageManager = new StorageManager(options, timestamp);
return storageManager.createDataDir('logs').then((logDir) => {
logging.configure(options, logDir);
}).then(() => {
if (log.isEnabledFor(log.VERBOSE)) {
Promise.longStackTraces();
}
log.info('Versions OS: %s sitespeed.io: %s browsertime: %s coach: %s', os.platform() + ' ' + os.release(), packageInfo.version, packageInfo.dependencies.browsertime, packageInfo.dependencies.webcoach);
}).then((pluginNames) => {
if (allInArray(['browsertime', 'coach'], pluginNames)) {
options.browsertime = merge({}, options.browsertime, {
coach: true
});
}
return pluginNames;
})
.then(() => {
return loader.loadPlugins(pluginNames)
.then((plugins) => {
let urlSources = [urlSource];
const allPlugins = urlSources.concat(plugins),
queueHandler = new QueueHandler(plugins, options);
return runOptionalFunction(allPlugins, 'open', {
storageManager,
timestamp
}, options)
.then(() => queueHandler.run(urlSources))
.tap((errors) => runOptionalFunction(allPlugins, 'close', options, errors));
})
})
.then((errors) => {
log.info('Finished analysing %s', options._);
return errors;
})
}
}

View File

@ -2,9 +2,9 @@
let log = require('intel');
module.exports.configure = function configure(options) {
module.exports.configure = function configure(options, logDir) {
options = options || {};
let level = log.INFO;
switch (options.verbose) {
case 1:
@ -29,4 +29,5 @@ module.exports.configure = function configure(options) {
'level': level
});
log.addHandler(new log.handlers.File(logDir + '/sitespeed.io.log'));
};