Skip to content

Commit

Permalink
fix: stop-parse was not being respected by commands (#1459)
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoe committed Oct 30, 2019
1 parent bc3c4d1 commit e78e76e
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 11 deletions.
12 changes: 10 additions & 2 deletions lib/command.js
Expand Up @@ -227,9 +227,12 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {

if (commandHandler.handler && !yargs._hasOutput()) {
yargs._setHasOutput()
// to simplify the parsing of positionals in commands,
// we temporarily populate '--' rather than _, with arguments
const populateDoubleDash = !!yargs.getOptions().configuration['populate--']
if (!populateDoubleDash) yargs._copyDoubleDash(innerArgv)

innerArgv = applyMiddleware(innerArgv, yargs, middlewares, false)

let handlerResult
if (isPromise(innerArgv)) {
handlerResult = innerArgv.then(argv => commandHandler.handler(argv))
Expand Down Expand Up @@ -349,7 +352,12 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
// short-circuit parse.
if (!unparsed.length) return

const parsed = Parser.detailed(unparsed, options)
const config = Object.assign({}, options.configuration, {
'populate--': true
})
const parsed = Parser.detailed(unparsed, Object.assign({}, options, {
configuration: config
}))

if (parsed.error) {
yargs.getUsageInstance().fail(parsed.error.message, parsed.error)
Expand Down
39 changes: 39 additions & 0 deletions test/command.js
Expand Up @@ -135,6 +135,45 @@ describe('Command', () => {
.parse()
parseCount.should.equal(1)
})

// see: https://github.com/yargs/yargs/issues/1457
it('handles -- in conjunction with positional arguments', () => {
let called = false
const argv = yargs('foo hello world series -- apple banana')
.command('foo <bar> [awesome...]', 'my awesome command', noop, (argv2) => {
argv2.bar.should.eql('hello')
argv2.awesome.should.eql(['world', 'series'])
argv2['_'].should.eql(['foo', 'apple', 'banana'])
called = true
})
.parse()
argv.bar.should.eql('hello')
argv.awesome.should.eql(['world', 'series'])
argv['_'].should.eql(['foo', 'apple', 'banana'])
called.should.equal(true)
})

// see: https://github.com/yargs/yargs/issues/1457
it('continues to support populate-- for commands, post #1457', () => {
let called = false
const argv = yargs('foo hello world series -- apple banana')
.command('foo <bar> [awesome...]', 'my awesome command', noop, (argv2) => {
argv2.bar.should.eql('hello')
argv2.awesome.should.eql(['world', 'series'])
argv2['_'].should.eql(['foo'])
argv2['--'].should.eql(['apple', 'banana'])
called = true
})
.parserConfiguration({
'populate--': true
})
.parse()
argv.bar.should.eql('hello')
argv.awesome.should.eql(['world', 'series'])
argv['_'].should.eql(['foo'])
argv['--'].should.eql(['apple', 'banana'])
called.should.equal(true)
})
})

describe('variadic', () => {
Expand Down
37 changes: 28 additions & 9 deletions yargs.js
Expand Up @@ -1025,21 +1025,27 @@ function Yargs (processArgs, cwd, parentRequire) {
enumerable: true
})

self._parseArgs = function parseArgs (args, shortCircuit, _skipValidation, commandIndex) {
let skipValidation = !!_skipValidation
self._parseArgs = function parseArgs (args, shortCircuit, _calledFromCommand, commandIndex) {
let skipValidation = !!_calledFromCommand
args = args || processArgs

options.__ = y18n.__
options.configuration = self.getParserConfiguration()

// Deprecated
let pkgConfig = pkgUp()['yargs']
if (pkgConfig) {
console.warn('Configuring yargs through package.json is deprecated and will be removed in a future major release, please use the JS API instead.')
options.configuration = Object.assign({}, pkgConfig, options.configuration)
}

const parsed = Parser.detailed(args, options)
const populateDoubleDash = !!options.configuration['populate--']
const config = Object.assign({}, options.configuration, {
'populate--': true
})
const parsed = Parser.detailed(args, Object.assign({}, options, {
configuration: config
}))

let argv = parsed.argv
if (parseContext) argv = Object.assign({}, argv, parseContext)
const aliases = parsed.aliases
Expand All @@ -1054,7 +1060,7 @@ function Yargs (processArgs, cwd, parentRequire) {
// are two passes through the parser. If completion
// is being performed short-circuit on the first pass.
if (shortCircuit) {
return argv
return (populateDoubleDash || _calledFromCommand) ? argv : self._copyDoubleDash(argv)
}

// if there's a handler associated with a
Expand Down Expand Up @@ -1087,7 +1093,8 @@ function Yargs (processArgs, cwd, parentRequire) {
// commands are executed using a recursive algorithm that executes
// the deepest command first; we keep track of the position in the
// argv._ array that is currently being executed.
return command.runCommand(cmd, self, parsed, i + 1)
const innerArgv = command.runCommand(cmd, self, parsed, i + 1)
return populateDoubleDash ? innerArgv : self._copyDoubleDash(innerArgv)
} else if (!firstUnknownCommand && cmd !== completionCommand) {
firstUnknownCommand = cmd
break
Expand All @@ -1096,7 +1103,8 @@ function Yargs (processArgs, cwd, parentRequire) {

// run the default command, if defined
if (command.hasDefaultCommand() && !skipDefaultCommand) {
return command.runCommand(null, self, parsed)
const innerArgv = command.runCommand(null, self, parsed)
return populateDoubleDash ? innerArgv : self._copyDoubleDash(innerArgv)
}

// recommend a command if recommendCommands() has
Expand All @@ -1113,7 +1121,8 @@ function Yargs (processArgs, cwd, parentRequire) {
self.exit(0)
}
} else if (command.hasDefaultCommand() && !skipDefaultCommand) {
return command.runCommand(null, self, parsed)
const innerArgv = command.runCommand(null, self, parsed)
return populateDoubleDash ? innerArgv : self._copyDoubleDash(innerArgv)
}

// we must run completions first, a user might
Expand All @@ -1131,7 +1140,7 @@ function Yargs (processArgs, cwd, parentRequire) {

self.exit(0)
})
return argv
return (populateDoubleDash || _calledFromCommand) ? argv : self._copyDoubleDash(argv)
}

// Handle 'help' and 'version' options
Expand Down Expand Up @@ -1175,6 +1184,16 @@ function Yargs (processArgs, cwd, parentRequire) {
else throw err
}

return (populateDoubleDash || _calledFromCommand) ? argv : self._copyDoubleDash(argv)
}

// to simplify the parsing of positionals in commands,
// we temporarily populate '--' rather than _, with arguments
// after the '--' directive. After the parse, we copy these back.
self._copyDoubleDash = function (argv) {
if (!argv._) return argv
argv._.push.apply(argv._, argv['--'])
delete argv['--']
return argv
}

Expand Down

0 comments on commit e78e76e

Please sign in to comment.