Skip to content

Commit

Permalink
feat: .help() API can now enable implicit help command (#574)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

introduces a default `help` command which outputs help, as an alternative to a help flag.
  • Loading branch information
nexdrew authored and bcoe committed Aug 7, 2016
1 parent 5deb939 commit 7645019
Show file tree
Hide file tree
Showing 4 changed files with 424 additions and 26 deletions.
28 changes: 22 additions & 6 deletions README.md
Expand Up @@ -1099,15 +1099,31 @@ var yargs = require('yargs')(['--help'])
Options:
--help Show help [boolean]

<a name="help"></a>.help([option, [description]])
------------------------------
<a name="help"></a>.help()
-----------------------------------------
.help([option | boolean])
-----------------------------------------
.help([option, [description | boolean]])
-----------------------------------------
.help([option, [description, [boolean]]])
-----------------------------------------

Add an option (e.g. `--help`) and implicit command that displays the usage
string and exits the process.

Add an option (e.g. `--help`) that displays the usage string and exits the
process. If present, the `description` parameter customizes the description of
If present, the `description` parameter customizes the description of
the help option in the usage string.

If invoked without parameters, `.help()` will make `--help` the option to trigger
help output.
If a boolean argument is provided, it will enable or disable the use of an
implicit command. The implicit command is enabled by default, but it can be
disabled by passing `false`.

Note that any multi-char aliases (e.g. `help`) used for the help option will
also be used for the implicit command. If there are no multi-char aliases (e.g.
`h`), then all single-char aliases will be used for the command.

If invoked without parameters, `.help()` will use `--help` as the option and
`help` as the implicit command to trigger help output.

Example:

Expand Down
77 changes: 77 additions & 0 deletions test/command.js
Expand Up @@ -470,6 +470,83 @@ describe('Command', function () {
})
})

describe('help command', function () {
it('displays command help appropriately', function () {
var sub = {
command: 'sub',
desc: 'Run the subcommand',
builder: {},
handler: function (argv) {}
}

var cmd = {
command: 'cmd <sub>',
desc: 'Try a command',
builder: function (yargs) {
return yargs.command(sub)
},
handler: function (argv) {}
}

var helpCmd = checkOutput(function () {
return yargs('help cmd')
.help().wrap(null)
.command(cmd)
.argv
}, [ './command' ])

var cmdHelp = checkOutput(function () {
return yargs('cmd help')
.help().wrap(null)
.command(cmd)
.argv
}, [ './command' ])

var helpCmdSub = checkOutput(function () {
return yargs('help cmd sub')
.help().wrap(null)
.command(cmd)
.argv
}, [ './command' ])

var cmdHelpSub = checkOutput(function () {
return yargs('cmd help sub')
.help().wrap(null)
.command(cmd)
.argv
}, [ './command' ])

var cmdSubHelp = checkOutput(function () {
return yargs('cmd sub help')
.help().wrap(null)
.command(cmd)
.argv
}, [ './command' ])

var expectedCmd = [
'./command cmd <sub>',
'Commands:',
' sub Run the subcommand',
'Options:',
' --help Show help [boolean]',
''
]

var expectedSub = [
'./command cmd sub',
'Options:',
' --help Show help [boolean]',
''
]

helpCmd.logs.join('\n').split(/\n+/).should.deep.equal(expectedCmd)
cmdHelp.logs.join('\n').split(/\n+/).should.deep.equal(expectedCmd)
helpCmdSub.logs.join('\n').split(/\n+/).should.deep.equal(expectedSub)
cmdHelpSub.logs.join('\n').split(/\n+/).should.deep.equal(expectedSub)
cmdSubHelp.logs.join('\n').split(/\n+/).should.deep.equal(expectedSub)
})
})

// addresses https://github.com/yargs/yargs/issues/514.
it('respects order of positional arguments when matching commands', function () {
var output = []
Expand Down
261 changes: 261 additions & 0 deletions test/yargs.js
Expand Up @@ -686,6 +686,11 @@ describe('yargs dsl tests', function () {
a1.why.should.equal('hello world')
a2.why.should.equal('hello world')
})

it('ignores implicit help command (with short-circuit)', function () {
var parsed = yargs.help().parse('help', true)
parsed._.should.deep.equal(['help'])
})
})

describe('config', function () {
Expand Down Expand Up @@ -1008,6 +1013,262 @@ describe('yargs dsl tests', function () {
argv.koala.should.equal(true)
})
})

describe('.help()', function () {
it('enables `--help` option and `help` command without arguments', function () {
var option = checkOutput(function () {
return yargs('--help')
.help()
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('help')
.help()
.wrap(null)
.argv
})
var expected = [
'Options:',
' --help Show help [boolean]',
''
]
option.logs[0].split('\n').should.deep.equal(expected)
command.logs[0].split('\n').should.deep.equal(expected)
})

it('enables `--help` option and `help` command with `true` argument', function () {
var option = checkOutput(function () {
return yargs('--help')
.help(true)
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('help')
.help(true)
.wrap(null)
.argv
})
var expected = [
'Options:',
' --help Show help [boolean]',
''
]
option.logs[0].split('\n').should.deep.equal(expected)
command.logs[0].split('\n').should.deep.equal(expected)
})

it('enables only `--help` option with `false` argument', function () {
var option = checkOutput(function () {
return yargs('--help')
.help(false)
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('help')
.help(false)
.wrap(null)
.argv
})
option.logs[0].split('\n').should.deep.equal([
'Options:',
' --help Show help [boolean]',
''
])
command.result.should.have.property('_').and.deep.equal(['help'])
})

it('enables given string as help option and command with string argument', function () {
var option = checkOutput(function () {
return yargs('--info')
.help('info')
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('info')
.help('info')
.wrap(null)
.argv
})
var helpOption = checkOutput(function () {
return yargs('--help')
.help('info')
.wrap(null)
.argv
})
var expected = [
'Options:',
' --info Show help [boolean]',
''
]
option.logs[0].split('\n').should.deep.equal(expected)
command.logs[0].split('\n').should.deep.equal(expected)
helpOption.result.should.have.property('help').and.be.true
})

it('enables given string as help option and command with string argument and `true` argument', function () {
var option = checkOutput(function () {
return yargs('--info')
.help('info', true)
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('info')
.help('info', true)
.wrap(null)
.argv
})
var helpOption = checkOutput(function () {
return yargs('--help')
.help('info', true)
.wrap(null)
.argv
})
var expected = [
'Options:',
' --info Show help [boolean]',
''
]
option.logs[0].split('\n').should.deep.equal(expected)
command.logs[0].split('\n').should.deep.equal(expected)
helpOption.result.should.have.property('help').and.be.true
})

it('enables given string as help option only with string argument and `false` argument', function () {
var option = checkOutput(function () {
return yargs('--info')
.help('info', false)
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('info')
.help('info', false)
.wrap(null)
.argv
})
option.logs[0].split('\n').should.deep.equal([
'Options:',
' --info Show help [boolean]',
''
])
command.result.should.have.property('_').and.deep.equal(['info'])
})

it('enables given string as help option and command with custom description with two string arguments', function () {
var option = checkOutput(function () {
return yargs('--info')
.help('info', 'Display info')
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('info')
.help('info', 'Display info')
.wrap(null)
.argv
})
var expected = [
'Options:',
' --info Display info [boolean]',
''
]
option.logs[0].split('\n').should.deep.equal(expected)
command.logs[0].split('\n').should.deep.equal(expected)
})

it('enables given string as help option and command with custom description with two string arguments and `true` argument', function () {
var option = checkOutput(function () {
return yargs('--info')
.help('info', 'Display info', true)
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('info')
.help('info', 'Display info', true)
.wrap(null)
.argv
})
var expected = [
'Options:',
' --info Display info [boolean]',
''
]
option.logs[0].split('\n').should.deep.equal(expected)
command.logs[0].split('\n').should.deep.equal(expected)
})

it('enables given string as help option only and custom description with two string arguments and `false` argument', function () {
var option = checkOutput(function () {
return yargs('--info')
.help('info', 'Display info', false)
.wrap(null)
.argv
})
var command = checkOutput(function () {
return yargs('info')
.help('info', 'Display info', false)
.wrap(null)
.argv
})
option.logs[0].split('\n').should.deep.equal([
'Options:',
' --info Display info [boolean]',
''
])
command.result.should.have.property('_').and.deep.equal(['info'])
})
})

describe('.help() with .alias()', function () {
it('uses multi-char (but not single-char) help alias as command', function () {
var info = checkOutput(function () {
return yargs('info')
.help().alias('h', 'help').alias('h', 'info')
.wrap(null)
.argv
})
var h = checkOutput(function () {
return yargs('h')
.help().alias('h', 'help').alias('h', 'info')
.wrap(null)
.argv
})
info.logs[0].split('\n').should.deep.equal([
'Options:',
' -h, --help, --info Show help [boolean]',
''
])
h.result.should.have.property('_').and.deep.equal(['h'])
})

it('uses single-char help alias as command if there are no multi-char aliases', function () {
var h = checkOutput(function () {
return yargs('h')
.help('h').alias('h', '?')
.wrap(null)
.argv
})
var q = checkOutput(function () {
return yargs('?')
.help('h').alias('h', '?')
.wrap(null)
.argv
})
var expected = [
'Options:',
' -h, -? Show help [boolean]',
''
]
h.logs[0].split('\n').should.deep.equal(expected)
q.logs[0].split('\n').should.deep.equal(expected)
})
})
})

describe('yargs context', function () {
Expand Down

0 comments on commit 7645019

Please sign in to comment.