diff options
author | FallenRiteMonk <fallenritemonk@gmail.com> | 2018-04-05 11:52:34 -0400 |
---|---|---|
committer | Myles Borins <mylesborins@google.com> | 2018-04-05 16:01:07 -0400 |
commit | 25a816dcda7b1db0929501acfe13f2fe5119759b (patch) | |
tree | d3df4377a11dfb643b5976d2048d9bb4ee527903 /deps/npm/node_modules/libnpx/node_modules/yargs/lib/command.js | |
parent | b29c36b80746733994257b7380245102bc3c4cd6 (diff) | |
download | android-node-v8-25a816dcda7b1db0929501acfe13f2fe5119759b.tar.gz android-node-v8-25a816dcda7b1db0929501acfe13f2fe5119759b.tar.bz2 android-node-v8-25a816dcda7b1db0929501acfe13f2fe5119759b.zip |
deps: upgrade npm to 5.8.0
PR-URL: https://github.com/nodejs/node/pull/19560
Fixes: https://github.com/nodejs/node/issues/19271
Reviewed-By: Michaƫl Zasso <targos@protonmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/npm/node_modules/libnpx/node_modules/yargs/lib/command.js')
-rw-r--r-- | deps/npm/node_modules/libnpx/node_modules/yargs/lib/command.js | 330 |
1 files changed, 210 insertions, 120 deletions
diff --git a/deps/npm/node_modules/libnpx/node_modules/yargs/lib/command.js b/deps/npm/node_modules/libnpx/node_modules/yargs/lib/command.js index 3567cf9532..65322dbbdb 100644 --- a/deps/npm/node_modules/libnpx/node_modules/yargs/lib/command.js +++ b/deps/npm/node_modules/libnpx/node_modules/yargs/lib/command.js @@ -1,67 +1,57 @@ -const path = require('path') +'use strict' + const inspect = require('util').inspect -const camelCase = require('camelcase') +const path = require('path') +const Parser = require('yargs-parser') -const DEFAULT_MARKER = '*' +const DEFAULT_MARKER = /(^\*)|(^\$0)/ // handles parsing positional arguments, // and populating argv with said positional // arguments. -module.exports = function (yargs, usage, validation) { +module.exports = function command (yargs, usage, validation) { const self = {} - - var handlers = {} - var aliasMap = {} - var defaultCommand - self.addHandler = function (cmd, description, builder, handler) { - var aliases = [] - handler = handler || function () {} - + let handlers = {} + let aliasMap = {} + let defaultCommand + self.addHandler = function addHandler (cmd, description, builder, handler, middlewares) { + let aliases = [] + handler = handler || (() => {}) + middlewares = middlewares || [] if (Array.isArray(cmd)) { aliases = cmd.slice(1) cmd = cmd[0] } else if (typeof cmd === 'object') { - var command = (Array.isArray(cmd.command) || typeof cmd.command === 'string') ? cmd.command : moduleName(cmd) + let command = (Array.isArray(cmd.command) || typeof cmd.command === 'string') ? cmd.command : moduleName(cmd) if (cmd.aliases) command = [].concat(command).concat(cmd.aliases) - self.addHandler(command, extractDesc(cmd), cmd.builder, cmd.handler) + self.addHandler(command, extractDesc(cmd), cmd.builder, cmd.handler, cmd.middlewares) return } // allow a module to be provided instead of separate builder and handler if (typeof builder === 'object' && builder.builder && typeof builder.handler === 'function') { - self.addHandler([cmd].concat(aliases), description, builder.builder, builder.handler) + self.addHandler([cmd].concat(aliases), description, builder.builder, builder.handler, builder.middlewares) return } // parse positionals out of cmd string - var parsedCommand = self.parseCommand(cmd) + const parsedCommand = self.parseCommand(cmd) // remove positional args from aliases only - aliases = aliases.map(function (alias) { - return self.parseCommand(alias).cmd - }) + aliases = aliases.map(alias => self.parseCommand(alias).cmd) // check for default and filter out '*'' - var isDefault = false - var parsedAliases = [parsedCommand.cmd].concat(aliases).filter(function (c) { - if (c === DEFAULT_MARKER) { + let isDefault = false + const parsedAliases = [parsedCommand.cmd].concat(aliases).filter((c) => { + if (DEFAULT_MARKER.test(c)) { isDefault = true return false } return true }) - // short-circuit if default with no aliases - if (isDefault && parsedAliases.length === 0) { - defaultCommand = { - original: cmd.replace(DEFAULT_MARKER, '').trim(), - handler: handler, - builder: builder || {}, - demanded: parsedCommand.demanded, - optional: parsedCommand.optional - } - return - } + // standardize on $0 for default command. + if (parsedAliases.length === 0 && isDefault) parsedAliases.push('$0') // shift cmd and aliases after filtering out '*' if (isDefault) { @@ -71,7 +61,7 @@ module.exports = function (yargs, usage, validation) { } // populate aliasMap - aliases.forEach(function (alias) { + aliases.forEach((alias) => { aliasMap[alias] = parsedCommand.cmd }) @@ -81,8 +71,10 @@ module.exports = function (yargs, usage, validation) { handlers[parsedCommand.cmd] = { original: cmd, - handler: handler, + description: description, + handler, builder: builder || {}, + middlewares: middlewares || [], demanded: parsedCommand.demanded, optional: parsedCommand.optional } @@ -90,16 +82,16 @@ module.exports = function (yargs, usage, validation) { if (isDefault) defaultCommand = handlers[parsedCommand.cmd] } - self.addDirectory = function (dir, context, req, callerFile, opts) { + self.addDirectory = function addDirectory (dir, context, req, callerFile, opts) { opts = opts || {} // disable recursion to support nested directories of subcommands if (typeof opts.recurse !== 'boolean') opts.recurse = false // exclude 'json', 'coffee' from require-directory defaults if (!Array.isArray(opts.extensions)) opts.extensions = ['js'] // allow consumer to define their own visitor function - const parentVisit = typeof opts.visit === 'function' ? opts.visit : function (o) { return o } + const parentVisit = typeof opts.visit === 'function' ? opts.visit : o => o // call addHandler via visitor function - opts.visit = function (obj, joined, filename) { + opts.visit = function visit (obj, joined, filename) { const visited = parentVisit(obj, joined, filename) // allow consumer to skip modules with their own visitor if (visited) { @@ -119,7 +111,7 @@ module.exports = function (yargs, usage, validation) { // if module was not require()d and no name given, throw error function moduleName (obj) { const mod = require('which-module')(obj) - if (!mod) throw new Error('No command name given for module: ' + inspect(obj)) + if (!mod) throw new Error(`No command name given for module: ${inspect(obj)}`) return commandFromFilename(mod.filename) } @@ -129,66 +121,62 @@ module.exports = function (yargs, usage, validation) { } function extractDesc (obj) { - for (var keys = ['describe', 'description', 'desc'], i = 0, l = keys.length, test; i < l; i++) { + for (let keys = ['describe', 'description', 'desc'], i = 0, l = keys.length, test; i < l; i++) { test = obj[keys[i]] if (typeof test === 'string' || typeof test === 'boolean') return test } return false } - self.parseCommand = function (cmd) { - var extraSpacesStrippedCommand = cmd.replace(/\s{2,}/g, ' ') - var splitCommand = extraSpacesStrippedCommand.split(/\s+(?![^[]*]|[^<]*>)/) - var bregex = /\.*[\][<>]/g - var parsedCommand = { + self.parseCommand = function parseCommand (cmd) { + const extraSpacesStrippedCommand = cmd.replace(/\s{2,}/g, ' ') + const splitCommand = extraSpacesStrippedCommand.split(/\s+(?![^[]*]|[^<]*>)/) + const bregex = /\.*[\][<>]/g + const parsedCommand = { cmd: (splitCommand.shift()).replace(bregex, ''), demanded: [], optional: [] } - splitCommand.forEach(function (cmd, i) { - var variadic = false + splitCommand.forEach((cmd, i) => { + let variadic = false cmd = cmd.replace(/\s/g, '') if (/\.+[\]>]/.test(cmd) && i === splitCommand.length - 1) variadic = true if (/^\[/.test(cmd)) { parsedCommand.optional.push({ cmd: cmd.replace(bregex, '').split('|'), - variadic: variadic + variadic }) } else { parsedCommand.demanded.push({ cmd: cmd.replace(bregex, '').split('|'), - variadic: variadic + variadic }) } }) return parsedCommand } - self.getCommands = function () { - return Object.keys(handlers).concat(Object.keys(aliasMap)) - } + self.getCommands = () => Object.keys(handlers).concat(Object.keys(aliasMap)) - self.getCommandHandlers = function () { - return handlers - } + self.getCommandHandlers = () => handlers - self.hasDefaultCommand = function () { - return !!defaultCommand - } + self.hasDefaultCommand = () => !!defaultCommand - self.runCommand = function (command, yargs, parsed, commandIndex) { - var aliases = parsed.aliases - var commandHandler = handlers[command] || handlers[aliasMap[command]] || defaultCommand - var currentContext = yargs.getContext() - var numFiles = currentContext.files.length - var parentCommands = currentContext.commands.slice() + self.runCommand = function runCommand (command, yargs, parsed, commandIndex) { + let aliases = parsed.aliases + const commandHandler = handlers[command] || handlers[aliasMap[command]] || defaultCommand + const currentContext = yargs.getContext() + let numFiles = currentContext.files.length + const parentCommands = currentContext.commands.slice() // what does yargs look like after the buidler is run? - var innerArgv = parsed.argv - var innerYargs = null - var positionalMap = {} - - if (command) currentContext.commands.push(command) + let innerArgv = parsed.argv + let innerYargs = null + let positionalMap = {} + if (command) { + currentContext.commands.push(command) + currentContext.fullCommands.push(commandHandler.original) + } if (typeof commandHandler.builder === 'function') { // a function can be provided, which builds // up a yargs chain and possibly returns it. @@ -198,8 +186,11 @@ module.exports = function (yargs, usage, validation) { // original command string as usage() for consistent behavior with // options object below. if (yargs.parsed === false) { - if (typeof yargs.getUsageInstance().getUsage() === 'undefined') { - yargs.usage('$0 ' + (parentCommands.length ? parentCommands.join(' ') + ' ' : '') + commandHandler.original) + if (shouldUpdateUsage(yargs)) { + yargs.getUsageInstance().usage( + usageFromParentCommandsCommandHandler(parentCommands, commandHandler), + commandHandler.description + ) } innerArgv = innerYargs ? innerYargs._parseArgs(null, null, true, commandIndex) : yargs._parseArgs(null, null, true, commandIndex) } else { @@ -212,8 +203,13 @@ module.exports = function (yargs, usage, validation) { // as a short hand, an object can instead be provided, specifying // the options that a command takes. innerYargs = yargs.reset(parsed.aliases) - innerYargs.usage('$0 ' + (parentCommands.length ? parentCommands.join(' ') + ' ' : '') + commandHandler.original) - Object.keys(commandHandler.builder).forEach(function (key) { + if (shouldUpdateUsage(innerYargs)) { + innerYargs.getUsageInstance().usage( + usageFromParentCommandsCommandHandler(parentCommands, commandHandler), + commandHandler.description + ) + } + Object.keys(commandHandler.builder).forEach((key) => { innerYargs.option(key, commandHandler.builder[key]) }) innerArgv = innerYargs._parseArgs(null, null, true, commandIndex) @@ -230,84 +226,178 @@ module.exports = function (yargs, usage, validation) { if (commandHandler.handler && !yargs._hasOutput()) { yargs._setHasOutput() - commandHandler.handler(innerArgv) + if (commandHandler.middlewares.length > 0) { + const middlewareArgs = commandHandler.middlewares.reduce(function (initialObj, middleware) { + return Object.assign(initialObj, middleware(innerArgv)) + }, {}) + Object.assign(innerArgv, middlewareArgs) + } + const handlerResult = commandHandler.handler(innerArgv) + if (handlerResult && typeof handlerResult.then === 'function') { + handlerResult.then( + null, + (error) => yargs.getUsageInstance().fail(null, error) + ) + } } - if (command) currentContext.commands.pop() + if (command) { + currentContext.commands.pop() + currentContext.fullCommands.pop() + } numFiles = currentContext.files.length - numFiles if (numFiles > 0) currentContext.files.splice(numFiles * -1, numFiles) return innerArgv } + function shouldUpdateUsage (yargs) { + return !yargs.getUsageInstance().getUsageDisabled() && + yargs.getUsageInstance().getUsage().length === 0 + } + + function usageFromParentCommandsCommandHandler (parentCommands, commandHandler) { + const c = DEFAULT_MARKER.test(commandHandler.original) ? commandHandler.original.replace(DEFAULT_MARKER, '').trim() : commandHandler.original + const pc = parentCommands.filter((c) => { return !DEFAULT_MARKER.test(c) }) + pc.push(c) + return `$0 ${pc.join(' ')}` + } + + self.runDefaultBuilderOn = function (yargs) { + if (shouldUpdateUsage(yargs)) { + // build the root-level command string from the default string. + const commandString = DEFAULT_MARKER.test(defaultCommand.original) + ? defaultCommand.original : defaultCommand.original.replace(/^[^[\]<>]*/, '$0 ') + yargs.getUsageInstance().usage( + commandString, + defaultCommand.description + ) + } + const builder = defaultCommand.builder + if (typeof builder === 'function') { + builder(yargs) + } else { + Object.keys(builder).forEach((key) => { + yargs.option(key, builder[key]) + }) + } + } + // transcribe all positional arguments "command <foo> <bar> [apple]" // onto argv. function populatePositionals (commandHandler, argv, context, yargs) { argv._ = argv._.slice(context.commands.length) // nuke the current commands - var demanded = commandHandler.demanded.slice(0) - var optional = commandHandler.optional.slice(0) - var positionalMap = {} + const demanded = commandHandler.demanded.slice(0) + const optional = commandHandler.optional.slice(0) + const positionalMap = {} validation.positionalCount(demanded.length, argv._.length) while (demanded.length) { - var demand = demanded.shift() - populatePositional(demand, argv, yargs, positionalMap) + const demand = demanded.shift() + populatePositional(demand, argv, positionalMap) } while (optional.length) { - var maybe = optional.shift() - populatePositional(maybe, argv, yargs, positionalMap) + const maybe = optional.shift() + populatePositional(maybe, argv, positionalMap) } argv._ = context.commands.concat(argv._) + + postProcessPositionals(argv, positionalMap, self.cmdToParseOptions(commandHandler.original)) + return positionalMap } - // populate a single positional argument and its - // aliases onto argv. - function populatePositional (positional, argv, yargs, positionalMap) { - // "positional" consists of the positional.cmd, an array representing - // the positional's name and aliases, and positional.variadic - // indicating whether or not it is a variadic array. - var variadics = null - var value = null - for (var i = 0, cmd; (cmd = positional.cmd[i]) !== undefined; i++) { - if (positional.variadic) { - if (variadics) argv[cmd] = variadics.slice(0) - else argv[cmd] = variadics = argv._.splice(0) - } else { - if (!value && !argv._.length) continue - if (value) argv[cmd] = value - else argv[cmd] = value = argv._.shift() - } - positionalMap[cmd] = true - postProcessPositional(yargs, argv, cmd) - addCamelCaseExpansions(argv, cmd) + function populatePositional (positional, argv, positionalMap, parseOptions) { + const cmd = positional.cmd[0] + if (positional.variadic) { + positionalMap[cmd] = argv._.splice(0).map(String) + } else { + if (argv._.length) positionalMap[cmd] = [String(argv._.shift())] } } - // TODO move positional arg logic to yargs-parser and remove this duplication - function postProcessPositional (yargs, argv, key) { - var coerce = yargs.getOptions().coerce[key] - if (typeof coerce === 'function') { - try { - argv[key] = coerce(argv[key]) - } catch (err) { - yargs.getUsageInstance().fail(err.message, err) - } + // we run yargs-parser against the positional arguments + // applying the same parsing logic used for flags. + function postProcessPositionals (argv, positionalMap, parseOptions) { + // combine the parsing hints we've inferred from the command + // string with explicitly configured parsing hints. + const options = Object.assign({}, yargs.getOptions()) + options.default = Object.assign(parseOptions.default, options.default) + options.alias = Object.assign(parseOptions.alias, options.alias) + options.array = options.array.concat(parseOptions.array) + + const unparsed = [] + Object.keys(positionalMap).forEach((key) => { + positionalMap[key].map((value) => { + unparsed.push(`--${key}`) + unparsed.push(value) + }) + }) + + // short-circuit parse. + if (!unparsed.length) return + + const parsed = Parser.detailed(unparsed, options) + + if (parsed.error) { + yargs.getUsageInstance().fail(parsed.error.message, parsed.error) + } else { + // only copy over positional keys (don't overwrite + // flag arguments that were already parsed). + const positionalKeys = Object.keys(positionalMap) + Object.keys(positionalMap).forEach((key) => { + [].push.apply(positionalKeys, parsed.aliases[key]) + }) + + Object.keys(parsed.argv).forEach((key) => { + if (positionalKeys.indexOf(key) !== -1) { + argv[key] = parsed.argv[key] + } + }) } } - function addCamelCaseExpansions (argv, option) { - if (/-/.test(option)) { - const cc = camelCase(option) - if (typeof argv[option] === 'object') argv[cc] = argv[option].slice(0) - else argv[cc] = argv[option] + self.cmdToParseOptions = function (cmdString) { + const parseOptions = { + array: [], + default: {}, + alias: {}, + demand: {} } + + const parsed = self.parseCommand(cmdString) + parsed.demanded.forEach((d) => { + const cmds = d.cmd.slice(0) + const cmd = cmds.shift() + if (d.variadic) { + parseOptions.array.push(cmd) + parseOptions.default[cmd] = [] + } + cmds.forEach((c) => { + parseOptions.alias[cmd] = c + }) + parseOptions.demand[cmd] = true + }) + + parsed.optional.forEach((o) => { + const cmds = o.cmd.slice(0) + const cmd = cmds.shift() + if (o.variadic) { + parseOptions.array.push(cmd) + parseOptions.default[cmd] = [] + } + cmds.forEach((c) => { + parseOptions.alias[cmd] = c + }) + }) + + return parseOptions } - self.reset = function () { + self.reset = () => { handlers = {} aliasMap = {} defaultCommand = undefined @@ -318,14 +408,14 @@ module.exports = function (yargs, usage, validation) { // the state of commands such that // we can apply .parse() multiple times // with the same yargs instance. - var frozen - self.freeze = function () { + let frozen + self.freeze = () => { frozen = {} frozen.handlers = handlers frozen.aliasMap = aliasMap frozen.defaultCommand = defaultCommand } - self.unfreeze = function () { + self.unfreeze = () => { handlers = frozen.handlers aliasMap = frozen.aliasMap defaultCommand = frozen.defaultCommand |