UNPKG

terraform-plus

Version:
223 lines (184 loc) 6.1 kB
'use strict'; const cli = require('commander'); const inquirer = require('inquirer'); const autocomplete = require('inquirer-autocomplete-prompt'); const pjson = require('../package'); const AbstractCommand = require('./abstract-command'); class TerraformPlus { construct() { this._currentCommand = null; this._logger = null; } /** * @desc * Run tfs [command] [options] [arguments] * * @example * let tfs = new TerraformPlus(); * tfs.run(process.argv); * * @param {Array} commandLine - entire command line passed to cli */ run(commandLine) { // customize default indentation this._defaultIndentation(); // setup cli version cli.version(pjson.version); // parse and remove global options from command line let parsed = commandLine.slice(2); let options = [ '-V', '--version', '-v', '--verbose', '-w', '--verbose2' ]; for (let i = parsed.length; i > 0; i--) { if (options.includes(parsed[i - 1])) { parsed.splice(i - 1, 1); } } // check for potential command name if (parsed.length > 0) { // validate that command name is supported this._parseCommand(parsed); // remove command from parsed command line //parsed = parsed.slice(1); } // no command provided else { // setup default command this._defaultCommand(); } // finish specifying commands, options and arguments, and parse the whole thing cli.arguments('[arguments]') .option('-v, --verbose', 'output warning messages by enabling verbose mode') .option('-w, --verbose2', 'output debugging messages by enabling verbose2 mode') .parse(commandLine); // enable verbose or debug logging capabilities if (cli.verbose) { this._logger.setLevel(this._logger.WARN); } else if (cli.verbose2) { this._logger.setLevel(this._logger.DEBUG); } // if no options, output help let showHelp = ((parsed.length <= 1 && parsed[0] === 'create') || parsed.length === 0); if (showHelp) { cli.outputHelp(); process.exit(0); } } /** * @private */ _defaultIndentation() { const helpInformation = cli.Command.prototype.helpInformation; const indentation = ' '; cli.Command.prototype.helpInformation = function () { return helpInformation.call(this) .split(/^/m) .reduce((accum, line) => { if (line === '\n') { const lastLine = accum[accum.length - 1]; if (!lastLine || !(lastLine === '\n' || lastLine.endsWith(':\n'))) { accum.push(line); } } else { accum.push(line.substr(indentation.length)); } return accum; }, []) .join(''); } } /** * @private */ _defaultCommand() { // setup command action and description cli.usage(`[command] [options] [arguments]`) .description(`tfs@${pjson.version} (built: ${pjson.buildDate})\n ${pjson.description}`); // setup command options AbstractCommand.COMMANDS_LIST.forEach(command => { if (typeof command !== 'undefined') { cli.command(command.name) .description(command.description); } }); // customize help output cli.on('--help', function() { console.log(`\nUse "tfs [command] --help" for more information about [command]`); }); // enable default logging capabilities this._logger = AbstractCommand.LOGGER; } /** * @desc Validates passed command name and set up it. * * @param {Array} parsed * * @private */ _parseCommand(parsed) { // validate that command name is supported if (AbstractCommand.COMMANDS_LIST.map(key => key.name).includes(parsed[0])) { this._currentCommand = parsed[0]; // setup command specific action and description const CommandClass = require(`${AbstractCommand.COMMANDS_PATH}/${this._currentCommand}`); cli.usage(`${parsed[0]} [options] [arguments]`) .description(`tfs@${pjson.version} (built: ${pjson.buildDate}) tfs ${this._currentCommand} will ${CommandClass.DESCRIPTION}`); if ((parsed.length >= 1 && parsed[0] !== 'create') || (parsed.length > 1 && parsed[0] === 'create')) { cli.action(commandName => { this._runCommand(commandName, parsed) }); } // setup command specific options CommandClass.OPTIONS.forEach(option => { if (option.hasOwnProperty('collect')) { cli.option(option.opt, option.desc, this.collect, []); } else { cli.option(option.opt, option.desc); } }); // enable default logging capabilities this._logger = CommandClass.LOGGER; } // command name is NOT supported else { console.log(`'${parsed[0]}' is not a valid tfs command`); console.log(`Use 'tfs --help' to see supported list of commands.`); process.exit(1); } } /** * * @param {String} val * @param {Array} memo * @return {*} */ collect(val, memo) { memo.push(val); return memo; } /** * Runs dynamicly tfs [command] * @param {String} commandName * @param {Object} parsed * @private */ async _runCommand(commandName, parsed) { const CommandClass = require(`${AbstractCommand.COMMANDS_PATH}/${commandName}`); const command = new CommandClass(cli, parsed); if (!(command instanceof AbstractCommand)) { throw new Error(`${commandName} must be an implementation of AbstractCommand class`); } if (command._cli.interactive) { inquirer.registerPrompt('autocomplete', autocomplete); await inquirer.prompt(CommandClass.QUESTIONS).then(answers => { // Use user feedback for ... whatever!! command.promt(answers); //command.run(); }); } if (parsed.indexOf('-h') > -1 || parsed.indexOf('--help') > -1) { command._cli.outputHelp(); process.exit(0); } command.run().then(res => {}).catch(err => this._logger.error(err)); } } module.exports = TerraformPlus;