Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: help always displayed for the first command parsed having an async handler #1535

Merged
merged 2 commits into from Feb 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/command.js
Expand Up @@ -256,6 +256,9 @@ module.exports = function command (yargs, usage, validation, globalMiddleware) {
// fail's throwing would cause an unhandled rejection.
}
})
.then(() => {
yargs.getUsageInstance().clearCachedHelpMessage()
})
} else {
if (handlerFinishCommand) {
handlerFinishCommand(handlerResult)
Expand Down
6 changes: 6 additions & 0 deletions lib/usage.js
Expand Up @@ -411,6 +411,12 @@ module.exports = function usage (yargs, y18n) {
cachedHelpMessage = this.help()
}

// however this snapshot must be cleared afterwards
// not to be be used by next calls to parse
self.clearCachedHelpMessage = function () {
cachedHelpMessage = undefined
}

// given a set of keys, place any keys that are
// ungrouped under the 'Options:' grouping.
function addUngroupedKeys (keys, aliases, groups) {
Expand Down
3 changes: 1 addition & 2 deletions test/helpers/utils.js
Expand Up @@ -34,8 +34,7 @@ exports.checkOutput = function checkOutput (f, argv, cb) {
}
process.emit = function emit (ev, value) {
if (ev === 'uncaughtException') {
done()
cb(value)
cb(value, done())
return true
}

Expand Down
74 changes: 73 additions & 1 deletion test/usage.js
Expand Up @@ -8,7 +8,7 @@ const yargs = require('../')
const rebase = require('../yargs').rebase
const YError = require('../lib/yerror')

require('chai').should()
const should = require('chai').should()

const noop = () => {}

Expand Down Expand Up @@ -3430,4 +3430,76 @@ describe('usage tests', () => {
])
})
})

describe('help message caching', () => {
it('should display proper usage when an async handler fails', (done) => {
const y = yargs()
.command('cmd', 'test command', {}, () => {
return new Promise((resolve, reject) =>
setTimeout(reject, 10)
)
})
.exitProcess(false)

checkUsage(
() => {
y.parse('cmd')
setTimeout(() => process.exit(1), 100)
},
undefined,
(err, r) => {
should.not.exist(err)
should.exist(r.errors[0])
r.errors[0].split('\n').should.deep.equal([
'_mocha cmd',
'',
'test command',
'',
'Options:',
' --help Show help [boolean]',
' --version Show version number [boolean]'
])
done()
}
)
})

it('should not display a cached help message for the next parsing', (done) => {
const y = yargs()
.command('cmd', 'test command', {}, () => {
return new Promise((resolve, reject) =>
setTimeout(resolve, 10)
)
})
.demandCommand(1, 'You need at least one command before moving on')
.exitProcess(false)

checkUsage(
() => {
y.parse('cmd')
setTimeout(() => {
y.parse('')
setTimeout(() => process.exit(1), 100)
}, 100)
},
undefined,
(err, r) => {
should.exist(err)
err.message.should.equal('You need at least one command before moving on')
should.exist(r.errors[0])
r.errors[0].split('\n').should.deep.equal([
'_mocha <command>',
'',
'Commands:',
' _mocha cmd test command',
'',
'Options:',
' --help Show help [boolean]',
' --version Show version number [boolean]'
])
done()
}
)
})
})
})