Skip to content

Commit

Permalink
fix(strict mode): report default command unknown arguments (#1626)
Browse files Browse the repository at this point in the history
  • Loading branch information
mleguen committed May 10, 2020
1 parent 59a5a56 commit 69f29a9
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 7 deletions.
2 changes: 1 addition & 1 deletion lib/command.js
Expand Up @@ -197,7 +197,7 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {

// 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 (!yargs._hasOutput()) yargs._runValidation(innerArgv, aliases, positionalMap, yargs.parsed.error, !command)

if (commandHandler.handler && !yargs._hasOutput()) {
yargs._setHasOutput()
Expand Down
13 changes: 9 additions & 4 deletions lib/validation.ts
Expand Up @@ -114,7 +114,7 @@ export function validation (yargs: YargsInstance, usage: UsageInstance, y18n: Y1
}

// check for unknown arguments (strict-mode).
self.unknownArguments = function unknownArguments (argv, aliases, positionalMap) {
self.unknownArguments = function unknownArguments (argv, aliases, positionalMap, isDefaultCommand) {
const commandKeys = yargs.getCommandInstance().getCommands()
const unknown: string[] = []
const currentContext = yargs.getContext()
Expand All @@ -129,7 +129,7 @@ export function validation (yargs: YargsInstance, usage: UsageInstance, y18n: Y1
}
})

if ((currentContext.commands.length > 0) || (commandKeys.length > 0)) {
if ((currentContext.commands.length > 0) || (commandKeys.length > 0) || isDefaultCommand) {
argv._.slice(currentContext.commands.length).forEach((key) => {
if (commandKeys.indexOf(key) === -1) {
unknown.push(key)
Expand Down Expand Up @@ -405,7 +405,7 @@ export function validation (yargs: YargsInstance, usage: UsageInstance, y18n: Y1
}

/** Instance of the validation module. */
interface ValidationInstance {
export interface ValidationInstance {
check(f: CustomCheck['func'], global: boolean): void
conflicting(argv: Arguments): void
conflicts(key: string, value: string | string[]): void
Expand All @@ -425,7 +425,12 @@ interface ValidationInstance {
requiredArguments(argv: Arguments): void
reset(localLookup: Dictionary): ValidationInstance
unfreeze(): void
unknownArguments(argv: Arguments, aliases: DetailedArguments['aliases'], positionalMap: Dictionary): void
unknownArguments(
argv: Arguments,
aliases: DetailedArguments['aliases'],
positionalMap: Dictionary,
isDefaultCommand: boolean
): void
unknownCommands(argv: Arguments): boolean
}

Expand Down
14 changes: 14 additions & 0 deletions test/validation.js
Expand Up @@ -320,6 +320,7 @@ describe('validation tests', () => {
return done()
})
.parse()
expect.fail('no parsing failure')
})

it('fails in strict mode with invalid command', (done) => {
Expand All @@ -333,6 +334,7 @@ describe('validation tests', () => {
return done()
})
.parse()
expect.fail('no parsing failure')
})

it('fails in strict mode with extra positionals', (done) => {
Expand All @@ -347,6 +349,18 @@ describe('validation tests', () => {
expect.fail('no parsing failure')
})

it('fails in strict mode with extra positionals for default command', (done) => {
yargs(['jumping', 'fast'])
.command('$0 <status>', 'kangaroo handlers')
.strict()
.fail((msg) => {
msg.should.equal('Unknown argument: fast')
return done()
})
.parse()
expect.fail('no parsing failure')
})

it('does not fail in strict mode when no commands configured', () => {
const argv = yargs('koala')
.demand(1)
Expand Down
4 changes: 2 additions & 2 deletions yargs.js
Expand Up @@ -1261,7 +1261,7 @@ function Yargs (processArgs, cwd, parentRequire) {
return argv
}

self._runValidation = function runValidation (argv, aliases, positionalMap, parseErrors) {
self._runValidation = function runValidation (argv, aliases, positionalMap, parseErrors, isDefaultCommand = false) {
if (parseErrors) throw new YError(parseErrors.message)
validation.nonOptionCount(argv)
validation.requiredArguments(argv)
Expand All @@ -1270,7 +1270,7 @@ function Yargs (processArgs, cwd, parentRequire) {
failedStrictCommands = validation.unknownCommands(argv)
}
if (strict && !failedStrictCommands) {
validation.unknownArguments(argv, aliases, positionalMap)
validation.unknownArguments(argv, aliases, positionalMap, isDefaultCommand)
}
validation.customChecks(argv, aliases)
validation.limitedChoices(argv)
Expand Down

0 comments on commit 69f29a9

Please sign in to comment.