Skip to content

Commit

Permalink
fix: make stdout flush on newer versions of Node.js (#501)
Browse files Browse the repository at this point in the history
* test: add failing test for #497

* fix: created shim that sets stdout/stderr to blocking when we know we're about to exit

* fix: OSX tests need a bit more running time

* fix: for the sake of Browserify, also check for _handle

* chore: pulled setBlocking shim into its own module
  • Loading branch information
bcoe committed May 15, 2016
1 parent 796285d commit 9f8c6f4
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 2 deletions.
3 changes: 3 additions & 0 deletions lib/usage.js
Expand Up @@ -5,6 +5,7 @@ var decamelize = require('decamelize')
var stringWidth = require('string-width')
var wsize = require('window-size')
var objFilter = require('./obj-filter')
var setBlocking = require('set-blocking')

module.exports = function (yargs, y18n) {
var __ = y18n.__
Expand Down Expand Up @@ -37,6 +38,8 @@ module.exports = function (yargs, y18n) {
f(msg, err)
})
} else {
if (yargs.getExitProcess()) setBlocking(true)

// don't output failure message more than once
if (!failureOutput) {
failureOutput = true
Expand Down
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -20,6 +20,7 @@
"pkg-conf": "^1.1.2",
"read-pkg-up": "^1.0.1",
"require-main-filename": "^1.0.1",
"set-blocking": "^1.0.0",
"string-width": "^1.0.1",
"window-size": "^0.2.0",
"y18n": "^3.2.1",
Expand All @@ -42,7 +43,7 @@
},
"scripts": {
"pretest": "standard",
"test": "nyc --cache mocha --require ./test/before.js --timeout=4000 --check-leaks",
"test": "nyc --cache mocha --require ./test/before.js --timeout=8000 --check-leaks",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"version": "standard-version"
},
Expand All @@ -69,4 +70,4 @@
"engine": {
"node": ">=0.10"
}
}
}
14 changes: 14 additions & 0 deletions test/fixtures/issue-497.js
@@ -0,0 +1,14 @@
#!/usr/bin/env node
var yargs = require('../../index')
var y = yargs.command('download <url> <files..>', 'make a get HTTP request')
.help()

for (var i = 0; i < 1000; i++) {
yargs.option('o' + i, {
describe: 'option ' + i
})
}

y.argv

console.log('never get here')
14 changes: 14 additions & 0 deletions test/integration.js
Expand Up @@ -56,6 +56,20 @@ describe('integration tests', function () {
})
})

// see #497
it('flushes all output when --help is executed', function (done) {
testCmd('./issue-497.js', [ '--help' ], function (code, stdout) {
if (code) {
done(new Error('cmd exited with code ' + code))
return
}

stdout.should.match(/--o999/)
stdout.should.not.match(/never get here/)
return done()
})
})

it('correctly fills positional command args with preceding option', function (done) {
testCmd('./opt-assignment-and-positional-command-arg.js', ['--foo', 'fOo', 'bar', 'bAz'], function (code, stdout) {
if (code) {
Expand Down
8 changes: 8 additions & 0 deletions yargs.js
Expand Up @@ -11,6 +11,7 @@ var readPkgUp = require('read-pkg-up')
var pkgConf = require('pkg-conf')
var requireMainFilename = require('require-main-filename')
var objFilter = require('./lib/obj-filter')
var setBlocking = require('set-blocking')

var exports = module.exports = Yargs
function Yargs (processArgs, cwd, parentRequire) {
Expand Down Expand Up @@ -649,6 +650,7 @@ function Yargs (processArgs, cwd, parentRequire) {

// generate a completion script for adding to ~/.bashrc.
if (completionCommand && ~argv._.indexOf(completionCommand) && !argv[completion.completionKey]) {
if (exitProcess) setBlocking(true)
self.showCompletionScript()
if (exitProcess) {
process.exit(0)
Expand All @@ -658,6 +660,8 @@ function Yargs (processArgs, cwd, parentRequire) {
// we must run completions first, a user might
// want to complete the --help or --version option.
if (completion.completionKey in argv) {
if (exitProcess) setBlocking(true)

// we allow for asynchronous completions,
// e.g., loading in a list of commands from an API.
var completionArgs = args.slice(args.indexOf('--' + completion.completionKey) + 1)
Expand All @@ -678,12 +682,16 @@ function Yargs (processArgs, cwd, parentRequire) {
// Handle 'help' and 'version' options
Object.keys(argv).forEach(function (key) {
if (key === helpOpt && argv[key]) {
if (exitProcess) setBlocking(true)

skipValidation = true
self.showHelp('log')
if (exitProcess) {
process.exit(0)
}
} else if (key === versionOpt && argv[key]) {
if (exitProcess) setBlocking(true)

skipValidation = true
usage.showVersion()
if (exitProcess) {
Expand Down

0 comments on commit 9f8c6f4

Please sign in to comment.