Skip to content

Commit

Permalink
Display help text for a subcommand when no parser is defined.
Browse files Browse the repository at this point in the history
When a subcommand has no sub-parser, we should inherit the options and
arguments of the parent parser, but overwrite the description text and
omit the subcommands, as parser-less subcommands can't have subcommands.

Refs #12325
  • Loading branch information
markstory committed Jul 5, 2018
1 parent 471acee commit cc76f51
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 25 deletions.
9 changes: 8 additions & 1 deletion src/Console/ConsoleOptionParser.php
Expand Up @@ -805,8 +805,15 @@ public function help($subcommand = null, $format = 'text', $width = 72)
if (isset($this->_subcommands[$subcommand])) {
$command = $this->_subcommands[$subcommand];
$subparser = $command->parser();

// Generate a parser as the subcommand didn't define one.
if (!($subparser instanceof self)) {
$subparser = clone $this;
// $subparser = clone $this;
$subparser = new self($subcommand);
$subparser
->setDescription($command->getRawHelp())
->addOptions($this->options())
->addArguments($this->arguments());
}
if (strlen($subparser->getDescription()) === 0) {
$subparser->setDescription($command->getRawHelp());
Expand Down
99 changes: 75 additions & 24 deletions tests/TestCase/Console/ConsoleOptionParserTest.php
Expand Up @@ -651,30 +651,6 @@ public function testSubcommandCamelBacked()
$this->assertEquals(['init_my_db'], $subcommands, 'Adding a subcommand does not work with camel backed method names.');
}

/**
* Test addSubcommand inherits options as no
* parser is created.
*
* @return void
*/
public function testAddSubcommandInheritOptions()
{
$parser = new ConsoleOptionParser('test', false);
$parser->addSubcommand('build', [
'help' => 'Build things'
])->addOption('connection', [
'short' => 'c',
'default' => 'default'
])->addArgument('name', ['required' => false]);

$result = $parser->parse(['build']);
$this->assertEquals('default', $result[0]['connection']);

$result = $parser->subcommands();
$this->assertArrayHasKey('build', $result);
$this->assertFalse($result['build']->parser(), 'No parser should be created');
}

/**
* test addSubcommand with an object.
*
Expand Down Expand Up @@ -785,6 +761,46 @@ public function testHelpSubcommandHelp()
--help, -h Display this help.
--zero, -0 Zero.
TEXT;
$this->assertTextEquals($expected, $result, 'Help is not correct.');
}

/**
* Test addSubcommand inherits options as no
* parser is created.
*
* @return void
*/
public function testHelpSubcommandInheritOptions()
{
$parser = new ConsoleOptionParser('mycommand', false);
$parser->addSubcommand('build', [
'help' => 'Build things.'
])->addSubcommand('destroy', [
'help' => 'Destroy things.'
])->addOption('connection', [
'help' => 'Db connection.',
'short' => 'c',
])->addArgument('name', ['required' => false]);

$result = $parser->help('build');
$expected = <<<TEXT
Build things.
<info>Usage:</info>
cake mycommand build [-c] [-h] [-q] [-v] [<name>]
<info>Options:</info>
--connection, -c Db connection.
--help, -h Display this help.
--quiet, -q Enable quiet output.
--verbose, -v Enable verbose output.
<info>Arguments:</info>
name <comment>(optional)</comment>
TEXT;
$this->assertTextEquals($expected, $result, 'Help is not correct.');
}
Expand Down Expand Up @@ -828,6 +844,41 @@ public function testHelpSubcommandHelpArray()
--quiet, -q Enable quiet output.
--verbose, -v Enable verbose output.
TEXT;
$this->assertTextEquals($expected, $result, 'Help is not correct.');
}

/**
* test that help() with a command param shows the help for a subcommand
*
* @return void
*/
public function testHelpSubcommandInheritParser()
{
$subParser = new ConsoleOptionParser('method', false);
$subParser->addOption('connection', ['help' => 'Db connection.']);
$subParser->addOption('zero', ['short' => '0', 'help' => 'Zero.']);

$parser = new ConsoleOptionParser('mycommand', false);
$parser->addSubcommand('method', [
'help' => 'This is another command',
'parser' => $subParser
])
->addOption('test', ['help' => 'A test option.']);

$result = $parser->help('method');
$expected = <<<TEXT
This is another command
<info>Usage:</info>
cake mycommand method [--connection] [-h] [-0]
<info>Options:</info>
--connection Db connection.
--help, -h Display this help.
--zero, -0 Zero.
TEXT;
$this->assertTextEquals($expected, $result, 'Help is not correct.');
}
Expand Down

0 comments on commit cc76f51

Please sign in to comment.