berlioz
Version:
Berlioz - cloud deployment and migration services
227 lines (202 loc) • 6.89 kB
JavaScript
const _ = require('the-lodash');
const Promise = require('the-promise');
const fs = require('fs');
const Path = require('path');
// const Vorpal = require('vorpal');
const Vorpal = require('../external/vorpal.git/dist/vorpal.js');
const HelpProcessor = require('../help-processor');
const Errors = require('./errors');
class VorpalInterface
{
constructor(logger, screen, executeCb, autocompleteProcessor)
{
this._logger = logger;
this._screen = screen;
this._executeCb = executeCb;
this._autocompleteProcessor = autocompleteProcessor;
this._vorpal = Vorpal();
this._commands = {};
}
accept(info, commandModule)
{
this._logger.verbose('Accepting %s...', info.includePath);
var name = info.command.join(' ');
this._commands[name] = {
info: info,
commandModule: commandModule
};
var command = this._vorpal
.command(name)
.action((args, callback) => {
this._processArgs(commandModule, args);
Promise.resolve(this._executeCb(info, commandModule, args))
.then(() => {
callback();
})
.catch(reason => {
callback("Something went wrong");
this._logger.exception(reason);
});
});
if (commandModule.arguments)
{
for(var x of commandModule.arguments)
{
this._acceptCommandArgument(commandModule, command, x);
}
}
if (commandModule.flags)
{
for(var x of commandModule.flags)
{
var str;
if (_.isObject(x)) {
str = '--' + x.name;
} else {
str = '--' + x;
}
command.option(str);
}
}
if (fs.existsSync(info.descrPath))
{
var descrContents = fs.readFileSync(info.descrPath, {encoding: 'utf8'});
var shortDescription;
var indexEnd = descrContents.indexOf('\n');
if (indexEnd == -1) {
shortDescription = descrContents;
} else {
shortDescription = descrContents.substring(0, indexEnd);
}
command.description(shortDescription);
command.help((args, callback) => {
this._screen.info(command.helpInformation());
var helpProc = new HelpProcessor()
helpProc.setTextOnly(true);
var cliHelp = helpProc.process(descrContents);
this._screen.info(cliHelp);
callback();
});
}
}
execUI(commandPath, options)
{
this._logger.verbose('RunUI %s...', commandPath, options);
var args = {
options: {}
};
if (options) {
args.options = options;
}
var name = commandPath.join(' ');
var command = this._commands[name];
if (!command) {
throw new Error(`Unknown command ${name}`);
}
args.options['fetch-only'] = true;
this._processArgs(command.commandModule, args);
return Promise.resolve(this._executeCb(command.info, command.commandModule, args))
}
_acceptCommandArgument(commandModule, command, x)
{
if (_.isObject(x)) {
var autocompleteName = x.name;
if (x.autocomplete_target) {
autocompleteName = x.autocomplete_target;
}
this._acceptCommandArgumentX(commandModule, command, x.name, x.optional, autocompleteName);
} else {
this._acceptCommandArgumentX(commandModule, command, x, false, x);
}
}
_acceptCommandArgumentX(commandModule, command, name, isOptional, autocompleteName)
{
var str = '--' + name + ' ';
if (isOptional) {
str += '[value]';
} else {
str += '<value>';
}
var autocompleteCb = null;
if (autocompleteName)
{
autocompleteCb = this._autocompleteProcessor(autocompleteName);
}
var massagedAutocompleteCb = null;
if (autocompleteCb)
{
massagedAutocompleteCb = (input, ctx) => {
var options = {};
for(var argument of commandModule.arguments)
{
var argumentName;
var autocompletionName;
if (_.isObject(argument)) {
argumentName = argument.name;
if (argument.autocomplete_target) {
autocompletionName = argument.autocomplete_target;
} else {
autocompletionName = argument.name;
}
} else {
argumentName = argument;
autocompletionName = argument;
}
if (argumentName in ctx.options)
{
options[autocompletionName] = ctx.options[argumentName];
}
}
ctx.options = options;
return autocompleteCb(input, ctx);
};
}
command.option(str, '', massagedAutocompleteCb);
}
interactive()
{
return this._vorpal
.delimiter('berlioz$')
.show();
}
exec(argStr)
{
this._logger.info('Running %s...', argStr);
_.remove(this._vorpal.commands, x => x._name == 'exit');
return this._vorpal.exec(argStr)
.then((data) => {
this._logger.info('CMD "%s" completed.', argStr);
this._logger.info(data);
if (data == 'Invalid command.') {
throw new Errors.Input(data);
}
return data;
})
}
_processArgs(commandModule, args)
{
if (commandModule.flags)
{
for(var x of commandModule.flags)
{
var name;
if (_.isObject(x)) {
name = x.name
} else {
name = x;
}
if (x in args.options)
{
if ((args.options[x] == true) || (args.options[x] == 'true')) {
args.options[x] = true;
} else {
args.options[x] = false;
}
} else {
args.options[x] = false;
}
}
}
}
}
module.exports = VorpalInterface;