diff options
Diffstat (limited to 'node_modules/yargs/lib')
-rw-r--r-- | node_modules/yargs/lib/apply-extends.js | 52 | ||||
-rw-r--r-- | node_modules/yargs/lib/argsert.js | 72 | ||||
-rw-r--r-- | node_modules/yargs/lib/command.js | 115 | ||||
-rw-r--r-- | node_modules/yargs/lib/completion.js | 7 | ||||
-rw-r--r-- | node_modules/yargs/lib/usage.js | 53 | ||||
-rw-r--r-- | node_modules/yargs/lib/validation.js | 39 | ||||
-rw-r--r-- | node_modules/yargs/lib/yerror.js | 10 |
7 files changed, 299 insertions, 49 deletions
diff --git a/node_modules/yargs/lib/apply-extends.js b/node_modules/yargs/lib/apply-extends.js new file mode 100644 index 000000000..5fc69fab1 --- /dev/null +++ b/node_modules/yargs/lib/apply-extends.js @@ -0,0 +1,52 @@ +var fs = require('fs') +var path = require('path') +var assign = require('./assign') +var YError = require('./yerror') + +var previouslyVisitedConfigs = [] + +function checkForCircularExtends (path) { + if (previouslyVisitedConfigs.indexOf(path) > -1) { + throw new YError("Circular extended configurations: '" + path + "'.") + } +} + +function getPathToDefaultConfig (cwd, pathToExtend) { + return path.resolve(cwd, pathToExtend) +} + +function applyExtends (config, cwd) { + var defaultConfig = {} + + if (config.hasOwnProperty('extends')) { + if (typeof config.extends !== 'string') return defaultConfig + var isPath = /\.json$/.test(config.extends) + var pathToDefault = null + if (!isPath) { + try { + pathToDefault = require.resolve(config.extends) + } catch (err) { + // most likely this simply isn't a module. + } + } else { + pathToDefault = getPathToDefaultConfig(cwd, config.extends) + } + // maybe the module uses key for some other reason, + // err on side of caution. + if (!pathToDefault && !isPath) return config + + checkForCircularExtends(pathToDefault) + + previouslyVisitedConfigs.push(pathToDefault) + + defaultConfig = isPath ? JSON.parse(fs.readFileSync(pathToDefault, 'utf8')) : require(config.extends) + delete config.extends + defaultConfig = applyExtends(defaultConfig, path.dirname(pathToDefault)) + } + + previouslyVisitedConfigs = [] + + return assign(defaultConfig, config) +} + +module.exports = applyExtends diff --git a/node_modules/yargs/lib/argsert.js b/node_modules/yargs/lib/argsert.js new file mode 100644 index 000000000..d3e72fce5 --- /dev/null +++ b/node_modules/yargs/lib/argsert.js @@ -0,0 +1,72 @@ +const command = require('./command')() +const YError = require('./yerror') + +const positionName = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'] + +module.exports = function (expected, callerArguments, length) { + // TODO: should this eventually raise an exception. + try { + // preface the argument description with "cmd", so + // that we can run it through yargs' command parser. + var position = 0 + var parsed = {demanded: [], optional: []} + if (typeof expected === 'object') { + length = callerArguments + callerArguments = expected + } else { + parsed = command.parseCommand('cmd ' + expected) + } + const args = [].slice.call(callerArguments) + + while (args.length && args[args.length - 1] === undefined) args.pop() + length = length || args.length + + if (length < parsed.demanded.length) { + throw new YError('Not enough arguments provided. Expected ' + parsed.demanded.length + + ' but received ' + args.length + '.') + } + + const totalCommands = parsed.demanded.length + parsed.optional.length + if (length > totalCommands) { + throw new YError('Too many arguments provided. Expected max ' + totalCommands + + ' but received ' + length + '.') + } + + parsed.demanded.forEach(function (demanded) { + const arg = args.shift() + const observedType = guessType(arg) + const matchingTypes = demanded.cmd.filter(function (type) { + return type === observedType || type === '*' + }) + if (matchingTypes.length === 0) argumentTypeError(observedType, demanded.cmd, position, false) + position += 1 + }) + + parsed.optional.forEach(function (optional) { + if (args.length === 0) return + const arg = args.shift() + const observedType = guessType(arg) + const matchingTypes = optional.cmd.filter(function (type) { + return type === observedType || type === '*' + }) + if (matchingTypes.length === 0) argumentTypeError(observedType, optional.cmd, position, true) + position += 1 + }) + } catch (err) { + console.warn(err.stack) + } +} + +function guessType (arg) { + if (Array.isArray(arg)) { + return 'array' + } else if (arg === null) { + return 'null' + } + return typeof arg +} + +function argumentTypeError (observedType, allowedTypes, position, optional) { + throw new YError('Invalid ' + (positionName[position] || 'manyith') + ' argument.' + + ' Expected ' + allowedTypes.join(' or ') + ' but received ' + observedType + '.') +} diff --git a/node_modules/yargs/lib/command.js b/node_modules/yargs/lib/command.js index c1afc1c55..3567cf953 100644 --- a/node_modules/yargs/lib/command.js +++ b/node_modules/yargs/lib/command.js @@ -2,6 +2,8 @@ const path = require('path') const inspect = require('util').inspect const camelCase = require('camelcase') +const DEFAULT_MARKER = '*' + // handles parsing positional arguments, // and populating argv with said positional // arguments. @@ -10,8 +12,11 @@ module.exports = function (yargs, usage, validation) { var handlers = {} var aliasMap = {} + var defaultCommand self.addHandler = function (cmd, description, builder, handler) { var aliases = [] + handler = handler || function () {} + if (Array.isArray(cmd)) { aliases = cmd.slice(1) cmd = cmd[0] @@ -28,15 +33,50 @@ module.exports = function (yargs, usage, validation) { return } - var parsedCommand = parseCommand(cmd) + // parse positionals out of cmd string + var parsedCommand = self.parseCommand(cmd) + + // remove positional args from aliases only aliases = aliases.map(function (alias) { - alias = parseCommand(alias).cmd // remove positional args + return 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) { + 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 + } + + // shift cmd and aliases after filtering out '*' + if (isDefault) { + parsedCommand.cmd = parsedAliases[0] + aliases = parsedAliases.slice(1) + cmd = cmd.replace(DEFAULT_MARKER, parsedCommand.cmd) + } + + // populate aliasMap + aliases.forEach(function (alias) { aliasMap[alias] = parsedCommand.cmd - return alias }) if (description !== false) { - usage.command(cmd, description, aliases) + usage.command(cmd, description, isDefault, aliases) } handlers[parsedCommand.cmd] = { @@ -46,6 +86,8 @@ module.exports = function (yargs, usage, validation) { demanded: parsedCommand.demanded, optional: parsedCommand.optional } + + if (isDefault) defaultCommand = handlers[parsedCommand.cmd] } self.addDirectory = function (dir, context, req, callerFile, opts) { @@ -94,7 +136,7 @@ module.exports = function (yargs, usage, validation) { return false } - function parseCommand (cmd) { + self.parseCommand = function (cmd) { var extraSpacesStrippedCommand = cmd.replace(/\s{2,}/g, ' ') var splitCommand = extraSpacesStrippedCommand.split(/\s+(?![^[]*]|[^<]*>)/) var bregex = /\.*[\][<>]/g @@ -130,48 +172,71 @@ module.exports = function (yargs, usage, validation) { return handlers } - self.runCommand = function (command, yargs, parsed) { - var argv = parsed.argv - var commandHandler = handlers[command] || handlers[aliasMap[command]] - var innerArgv = argv + self.hasDefaultCommand = function () { + return !!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() - currentContext.commands.push(command) + + // 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) if (typeof commandHandler.builder === 'function') { // a function can be provided, which builds // up a yargs chain and possibly returns it. - innerArgv = commandHandler.builder(yargs.reset(parsed.aliases)) + innerYargs = commandHandler.builder(yargs.reset(parsed.aliases)) // if the builder function did not yet parse argv with reset yargs // and did not explicitly set a usage() string, then apply the // original command string as usage() for consistent behavior with - // options object below + // options object below. if (yargs.parsed === false) { if (typeof yargs.getUsageInstance().getUsage() === 'undefined') { yargs.usage('$0 ' + (parentCommands.length ? parentCommands.join(' ') + ' ' : '') + commandHandler.original) } - innerArgv = innerArgv ? innerArgv.argv : yargs.argv + innerArgv = innerYargs ? innerYargs._parseArgs(null, null, true, commandIndex) : yargs._parseArgs(null, null, true, commandIndex) } else { innerArgv = yargs.parsed.argv } + + if (innerYargs && yargs.parsed === false) aliases = innerYargs.parsed.aliases + else aliases = yargs.parsed.aliases } else if (typeof commandHandler.builder === 'object') { // as a short hand, an object can instead be provided, specifying // the options that a command takes. - innerArgv = yargs.reset(parsed.aliases) - innerArgv.usage('$0 ' + (parentCommands.length ? parentCommands.join(' ') + ' ' : '') + commandHandler.original) + innerYargs = yargs.reset(parsed.aliases) + innerYargs.usage('$0 ' + (parentCommands.length ? parentCommands.join(' ') + ' ' : '') + commandHandler.original) Object.keys(commandHandler.builder).forEach(function (key) { - innerArgv.option(key, commandHandler.builder[key]) + innerYargs.option(key, commandHandler.builder[key]) }) - innerArgv = innerArgv.argv + innerArgv = innerYargs._parseArgs(null, null, true, commandIndex) + aliases = innerYargs.parsed.aliases + } + + if (!yargs._hasOutput()) { + positionalMap = populatePositionals(commandHandler, innerArgv, currentContext, yargs) } - if (!yargs._hasOutput()) populatePositionals(commandHandler, innerArgv, currentContext, yargs) + + // we apply validation post-hoc, so that custom + // checks get passed populated positional arguments. + if (!yargs._hasOutput()) yargs._runValidation(innerArgv, aliases, positionalMap, yargs.parsed.error) if (commandHandler.handler && !yargs._hasOutput()) { + yargs._setHasOutput() commandHandler.handler(innerArgv) } - currentContext.commands.pop() + + if (command) currentContext.commands.pop() numFiles = currentContext.files.length - numFiles if (numFiles > 0) currentContext.files.splice(numFiles * -1, numFiles) + return innerArgv } @@ -181,25 +246,27 @@ module.exports = function (yargs, usage, validation) { argv._ = argv._.slice(context.commands.length) // nuke the current commands var demanded = commandHandler.demanded.slice(0) var optional = commandHandler.optional.slice(0) + var positionalMap = {} validation.positionalCount(demanded.length, argv._.length) while (demanded.length) { var demand = demanded.shift() - populatePositional(demand, argv, yargs) + populatePositional(demand, argv, yargs, positionalMap) } while (optional.length) { var maybe = optional.shift() - populatePositional(maybe, argv, yargs) + populatePositional(maybe, argv, yargs, positionalMap) } argv._ = context.commands.concat(argv._) + return positionalMap } // populate a single positional argument and its // aliases onto argv. - function populatePositional (positional, argv, yargs) { + 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. @@ -214,6 +281,7 @@ module.exports = function (yargs, usage, validation) { if (value) argv[cmd] = value else argv[cmd] = value = argv._.shift() } + positionalMap[cmd] = true postProcessPositional(yargs, argv, cmd) addCamelCaseExpansions(argv, cmd) } @@ -242,6 +310,7 @@ module.exports = function (yargs, usage, validation) { self.reset = function () { handlers = {} aliasMap = {} + defaultCommand = undefined return self } @@ -254,10 +323,12 @@ module.exports = function (yargs, usage, validation) { frozen = {} frozen.handlers = handlers frozen.aliasMap = aliasMap + frozen.defaultCommand = defaultCommand } self.unfreeze = function () { handlers = frozen.handlers aliasMap = frozen.aliasMap + defaultCommand = frozen.defaultCommand frozen = undefined } diff --git a/node_modules/yargs/lib/completion.js b/node_modules/yargs/lib/completion.js index 93a936cf6..5cd9a18a0 100644 --- a/node_modules/yargs/lib/completion.js +++ b/node_modules/yargs/lib/completion.js @@ -44,7 +44,12 @@ module.exports = function (yargs, usage, command) { var handlers = command.getCommandHandlers() for (var i = 0, ii = args.length; i < ii; ++i) { if (handlers[args[i]] && handlers[args[i]].builder) { - return handlers[args[i]].builder(yargs.reset()).argv + const builder = handlers[args[i]].builder + if (typeof builder === 'function') { + const y = yargs.reset() + builder(y) + return y.argv + } } } diff --git a/node_modules/yargs/lib/usage.js b/node_modules/yargs/lib/usage.js index 555ffb52b..43f71225c 100644 --- a/node_modules/yargs/lib/usage.js +++ b/node_modules/yargs/lib/usage.js @@ -3,6 +3,7 @@ const stringWidth = require('string-width') const objFilter = require('./obj-filter') const setBlocking = require('set-blocking') +const YError = require('./yerror') module.exports = function (yargs, y18n) { const __ = y18n.__ @@ -50,7 +51,7 @@ module.exports = function (yargs, y18n) { } } - err = err || new Error(msg) + err = err || new YError(msg) if (yargs.getExitProcess()) { return yargs.exit(1) } else if (yargs._hasParseCallback()) { @@ -76,8 +77,15 @@ module.exports = function (yargs, y18n) { } var commands = [] - self.command = function (cmd, description, aliases) { - commands.push([cmd, description || '', aliases]) + self.command = function (cmd, description, isDefault, aliases) { + // the last default wins, so cancel out any previously set default + if (isDefault) { + commands = commands.map(function (cmdArray) { + cmdArray[2] = false + return cmdArray + }) + } + commands.push([cmd, description || '', isDefault, aliases]) } self.getCommands = function () { return commands @@ -165,8 +173,13 @@ module.exports = function (yargs, y18n) { {text: command[0], padding: [0, 2, 0, 2], width: maxWidth(commands, theWrap) + 4}, {text: command[1]} ) - if (command[2] && command[2].length) { - ui.div({text: '[' + __('aliases:') + ' ' + command[2].join(', ') + ']', padding: [0, 0, 0, 2], align: 'right'}) + var hints = [] + if (command[2]) hints.push('[' + __('default:').slice(0, -1) + ']') // TODO hacking around i18n here + if (command[3] && command[3].length) { + hints.push('[' + __('aliases:') + ' ' + command[3].join(', ') + ']') + } + if (hints.length) { + ui.div({text: hints.join(' '), padding: [0, 0, 0, 2], align: 'right'}) } else { ui.div() } @@ -234,7 +247,7 @@ module.exports = function (yargs, y18n) { var extra = [ type, - demandedOptions[key] ? '[' + __('required') + ']' : null, + (key in demandedOptions) ? '[' + __('required') + ']' : null, options.choices && options.choices[key] ? '[' + __('choices:') + ' ' + self.stringifiedValues(options.choices[key]) + ']' : null, defaultString(options.default[key], options.defaultDescription[key]) @@ -261,10 +274,24 @@ module.exports = function (yargs, y18n) { }) examples.forEach(function (example) { - ui.div( - {text: example[0], padding: [0, 2, 0, 2], width: maxWidth(examples, theWrap) + 4}, - example[1] - ) + if (example[1] === '') { + ui.div( + { + text: example[0], + padding: [0, 2, 0, 2] + } + ) + } else { + ui.div( + { + text: example[0], + padding: [0, 2, 0, 2], + width: maxWidth(examples, theWrap) + 4 + }, { + text: example[1] + } + ) + } }) ui.div() @@ -315,7 +342,7 @@ module.exports = function (yargs, y18n) { // copy descriptions. if (descriptions[alias]) self.describe(key, descriptions[alias]) // copy demanded. - if (demandedOptions[alias]) yargs.demandOption(key, demandedOptions[alias].msg) + if (alias in demandedOptions) yargs.demandOption(key, demandedOptions[alias]) // type messages. if (~options.boolean.indexOf(alias)) yargs.boolean(key) if (~options.count.indexOf(alias)) yargs.count(key) @@ -421,7 +448,7 @@ module.exports = function (yargs, y18n) { else logger.log(version) } - self.reset = function (globalLookup) { + self.reset = function (localLookup) { // do not reset wrap here // do not reset fails here failMessage = null @@ -431,7 +458,7 @@ module.exports = function (yargs, y18n) { examples = [] commands = [] descriptions = objFilter(descriptions, function (k, v) { - return globalLookup[k] + return !localLookup[k] }) return self } diff --git a/node_modules/yargs/lib/validation.js b/node_modules/yargs/lib/validation.js index 328d83aff..2f9ff8e6c 100644 --- a/node_modules/yargs/lib/validation.js +++ b/node_modules/yargs/lib/validation.js @@ -1,4 +1,5 @@ const objFilter = require('./obj-filter') +const specialKeys = ['$0', '--', '_'] // validation-type-stuff, missing params, // bad implications, custom checks. @@ -89,7 +90,7 @@ module.exports = function (yargs, usage, y18n) { var missing = null Object.keys(demandedOptions).forEach(function (key) { - if (!argv.hasOwnProperty(key)) { + if (!argv.hasOwnProperty(key) || typeof argv[key] === 'undefined') { missing = missing || {} missing[key] = demandedOptions[key] } @@ -98,7 +99,7 @@ module.exports = function (yargs, usage, y18n) { if (missing) { const customMsgs = [] Object.keys(missing).forEach(function (key) { - const msg = missing[key].msg + const msg = missing[key] if (msg && customMsgs.indexOf(msg) < 0) { customMsgs.push(msg) } @@ -116,7 +117,7 @@ module.exports = function (yargs, usage, y18n) { } // check for unknown arguments (strict-mode). - self.unknownArguments = function (argv, aliases) { + self.unknownArguments = function (argv, aliases, positionalMap) { const aliasLookup = {} const descriptions = usage.getDescriptions() const demandedOptions = yargs.getDemandedOptions() @@ -131,9 +132,11 @@ module.exports = function (yargs, usage, y18n) { }) Object.keys(argv).forEach(function (key) { - if (key !== '$0' && key !== '_' && + if (specialKeys.indexOf(key) === -1 && !descriptions.hasOwnProperty(key) && !demandedOptions.hasOwnProperty(key) && + !positionalMap.hasOwnProperty(key) && + !yargs._getParseContext().hasOwnProperty(key) && !aliasLookup.hasOwnProperty(key)) { unknown.push(key) } @@ -165,7 +168,7 @@ module.exports = function (yargs, usage, y18n) { if (!Object.keys(options.choices).length) return Object.keys(argv).forEach(function (key) { - if (key !== '$0' && key !== '_' && + if (specialKeys.indexOf(key) === -1 && options.choices.hasOwnProperty(key)) { [].concat(argv[key]).forEach(function (value) { // TODO case-insensitive configurability @@ -194,22 +197,26 @@ module.exports = function (yargs, usage, y18n) { // custom checks, added using the `check` option on yargs. var checks = [] - self.check = function (f) { - checks.push(f) + self.check = function (f, global) { + checks.push({ + func: f, + global: global + }) } self.customChecks = function (argv, aliases) { for (var i = 0, f; (f = checks[i]) !== undefined; i++) { + var func = f.func var result = null try { - result = f(argv, aliases) + result = func(argv, aliases) } catch (err) { usage.fail(err.message ? err.message : err, err) continue } if (!result) { - usage.fail(__('Argument check failed: %s', f.toString())) + usage.fail(__('Argument check failed: %s', func.toString())) } else if (typeof result === 'string' || result instanceof Error) { usage.fail(result.toString(), result) } @@ -224,6 +231,7 @@ module.exports = function (yargs, usage, y18n) { self.implies(k, key[k]) }) } else { + yargs.global(key) implied[key] = value } } @@ -290,6 +298,7 @@ module.exports = function (yargs, usage, y18n) { self.conflicts(k, key[k]) }) } else { + yargs.global(key) conflicting[key] = value } } @@ -324,12 +333,16 @@ module.exports = function (yargs, usage, y18n) { if (recommended) usage.fail(__('Did you mean %s?', recommended)) } - self.reset = function (globalLookup) { + self.reset = function (localLookup) { implied = objFilter(implied, function (k, v) { - return globalLookup[k] + return !localLookup[k] + }) + conflicting = objFilter(conflicting, function (k, v) { + return !localLookup[k] + }) + checks = checks.filter(function (c) { + return c.global }) - checks = [] - conflicting = {} return self } diff --git a/node_modules/yargs/lib/yerror.js b/node_modules/yargs/lib/yerror.js new file mode 100644 index 000000000..ad96a8776 --- /dev/null +++ b/node_modules/yargs/lib/yerror.js @@ -0,0 +1,10 @@ +function YError (msg) { + this.name = 'YError' + this.message = msg || 'yargs error' + Error.captureStackTrace(this, YError) +} + +YError.prototype = Object.create(Error.prototype) +YError.prototype.constructor = YError + +module.exports = YError |