UNPKG

runas-core

Version:

The adhesive orchestrator

212 lines (184 loc) 6.4 kB
'use strict'; const path = require('path'); const moment = require('moment'); const params = require('./params'); const config = require('./config').setOptions({isGlobal: !params.onlyLocal}); const analytics = require('./analytics'); const bus = require('./bus'); const context = require('./context'); const docs = require('./docs'); const execution = require('./execution'); const logger = require('./logger'); const scullion = require('./globalScullion'); const sipper = require('./sipper'); const stepper = require('./stepper'); /** * Sour is the commands line interface * @returns gush : execute the commands. * @constructor Sour */ module.exports = function() { const _config = config.get(); /** * Normalize commands getting context * * @returns {{name: *, context: *, orig: *, recipe: *, isStep: *}} * @private */ const normalize = function(command) { logger.trace('#green', 'sour:normalize:', 'commands:', command); if (Object.prototype.toString.call(command) === '[object Array]') { command = command[0]; if (!command) { command = ''; } } const normal = {}; normal.orig = normal.name = command; if (command.indexOf(':') >= 0) { const names = command.split(':'); normal.context = names[0]; if (names.length === 3) { normal.isStep = true; normal.name = names[2]; } else { normal.name = names[1]; } } if (normal.context) { const exists = Object.getOwnPropertyNames(_config.contexts).find(name => name === normal.context); normal.context = [ normal.context ]; normal.contextFixed = true; if (!exists) { logger.error('#red', 'ERROR:', '#cyan', normal.context, 'is not a software unit in the configuration'); normal.context = undefined; } } else { normal.context = context.whoami(); normal.context = normal.context.length > 0 ? normal.context : undefined; } if (params.all) { normal.context = config.allContexts(); } if (!normal.isStep) { normal.flowName = normal.name; } params.normal = JSON.parse(JSON.stringify(normal)); return normal; }; /** * checks if the params is available and compatible with configurations * @param reject : callback function * @private */ const check = function(reject, cb) { logger.trace('#green', 'sour:check:', 'commands:', params.commands); const normal = normalize(params.commands); if (normal.orig === '') { return docs.help(normal, cb); } if (!normal.context) { logger.error('#red', 'ERROR:', 'command', '#cyan', normal.orig, 'needs a context of execution'); return reject(); } if (config.isAvailable(normal)) { return normal; } if (normal.name) { const type = normal.isStep ? 'step' : 'flow'; logger.error(type, '#green', normal.orig, '#red', 'doesn\'t exist!'); logger.txt('\n', _config.cmd, '-la for help.', '\n'); return reject('command not available'); } return docs.help(normal, cb); }; /** * Execute all the commands of the utility * @returns {Promise} */ const gush = function(init) { return docs.showDisclaimer().then(() => new Promise((resolve, reject) => { logger.trace('#green', 'sour:gush', 'commands:', params.commands); const _resolve = function() { const lastFinished = execution.lastFinished('flow') || execution.lastFinished('step'); if (lastFinished.stats.hardOk()) { bus.emit('command:end', { status: 0 }); resolve.apply(this, arguments); } else { bus.emit('command:end', { status: 1 }); reject.apply(this, arguments); } }; const _reject = function() { if (arguments[0].notBuilt) { logger.info('Execution', '#green', 'NOT BUILT'); bus.emit('command:end', {status: 2}); resolve.apply(this, arguments); } else { bus.emit('command:end', {status: 1}); reject.apply(this, arguments); } }; const execute = function(normal) { logger.info('Execution contexts:', '[', '#bold', normal.context.join(', '), ']'); bus.emit('command:start', normal); if (normal.isStep) { normal.params = config.getStepParams(normal); normal.context.map(ctx => analytics.hit(`/steps/${ctx}::${normal.name}`, `step: ${ctx}::${normal.name}`)); stepper.execute(normal, _resolve, _reject); } else { normal.context.map(ctx => analytics.hit(`/flows/${ctx}:${normal.name}`, `flow: ${ctx}:${normal.name}`)); sipper.execute(normal, params.initStep, params.endStep, _resolve, _reject); } }; const executeAnswers = function(answers) { try { const command = answers.command && !answers.step ? answers.command : answers.step; params.commands.push(command); execute(normalize([ command ])); } catch (e) { console.error(e.stack); reject(e); } }; try { if (params.version) { docs.version(); resolve(); } else if (params.functionalTests) { require('./functionalTests').run(resolve, reject); } else if (params.saveRequirements && params.commands.length === 0) { config.saveRequirements().then(resolve, reject); } else if (params.writeCache) { scullion.writeCache(); resolve(); } else if (params.showContext) { logger.txt(context.whoami()); resolve(); } else { const normal = check(reject, executeAnswers); if (normal) { normal.init = init; if (params.help) { docs.help(normal); resolve(); } else { execute(normal); } } } // Commented until domain implementation were undone //if (!params.writeCache) { // const spawn = require('child_process').spawn; // spawn(process.execPath, [path.join(config.getDir('module'), 'bin', 'runas.js'), '-w'], {stdio: ['ignore', process.stdout, process.stderr]}); //} } catch (e) { console.error(e.stack); reject(e); } })); }; return { gush: gush }; };