Skip to content

Commit

Permalink
Merge pull request #17642 from alphp/patch-2
Browse files Browse the repository at this point in the history
Console Commands: Add default value for arguments
  • Loading branch information
othercorey committed Apr 14, 2024
2 parents 0c2a604 + 6130945 commit 335e01d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 10 deletions.
27 changes: 26 additions & 1 deletion src/Console/ConsoleInputArgument.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,23 @@ class ConsoleInputArgument
*/
protected $_choices;

/**
* Default value for the argument.
*
* @var string|null
*/
protected $_default;

/**
* Make a new Input Argument
*
* @param array<string, mixed>|string $name The long name of the option, or an array with all the properties.
* @param string $help The help text for this option
* @param bool $required Whether this argument is required. Missing required args will trigger exceptions
* @param array<string> $choices Valid choices for this option.
* @param string|null $default The default value for this argument.
*/
public function __construct($name, $help = '', $required = false, $choices = [])
public function __construct($name, $help = '', $required = false, $choices = [], $default = null)
{
if (is_array($name) && isset($name['name'])) {
foreach ($name as $key => $value) {
Expand All @@ -75,6 +83,7 @@ public function __construct($name, $help = '', $required = false, $choices = [])
$this->_help = $help;
$this->_required = $required;
$this->_choices = $choices;
$this->_default = $default;
}
}

Expand Down Expand Up @@ -119,6 +128,9 @@ public function help(int $width = 0): string
if ($this->_choices) {
$optional .= sprintf(' <comment>(choices: %s)</comment>', implode('|', $this->_choices));
}
if ($this->_default !== null) {
$optional .= sprintf(' <comment>default: "%s"</comment>', $this->_default);
}

return sprintf('%s%s%s', $name, $this->_help, $optional);
}
Expand All @@ -142,6 +154,16 @@ public function usage(): string
return $name;
}

/**
* Get the default value for this argument
*
* @return string|null
*/
public function defaultValue()
{
return $this->_default;
}

/**
* Check if this argument is a required argument
*
Expand Down Expand Up @@ -194,6 +216,9 @@ public function xml(SimpleXMLElement $parent): SimpleXMLElement
foreach ($this->_choices as $valid) {
$choices->addChild('choice', $valid);
}
if ($this->_default !== null) {
$option->addAttribute('default', $this->_default);
}

return $parent;
}
Expand Down
13 changes: 9 additions & 4 deletions src/Console/ConsoleOptionParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -725,10 +725,15 @@ public function parse(array $argv, ?ConsoleIo $io = null): array
}

foreach ($this->_args as $i => $arg) {
if ($arg->isRequired() && !isset($args[$i])) {
throw new ConsoleException(
sprintf('Missing required argument. The `%s` argument is required.', $arg->name())
);
if (!isset($args[$i])) {
if ($arg->isRequired()) {
throw new ConsoleException(
sprintf('Missing required argument. The `%s` argument is required.', $arg->name())
);
}
if ($arg->defaultValue() !== null) {
$args[$i] = $arg->defaultValue();
}
}
}
foreach ($this->_options as $option) {
Expand Down
33 changes: 30 additions & 3 deletions tests/TestCase/Console/ConsoleOptionParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,18 @@ public function testAddArgument(): void
$this->assertEquals($parser, $result, 'Should return this');
}

/**
* test positional argument parsing.
*/
public function testAddArgumentWithDefault(): void
{
$parser = new ConsoleOptionParser('test', false);
$result = $parser->addArgument('name', ['help' => 'An argument', 'default' => 'foo']);
$args = $parser->arguments();
$this->assertEquals($parser, $result, 'Should return this');
$this->assertEquals('foo', $args[0]->defaultValue());
}

/**
* Add arguments that were once considered the same
*/
Expand Down Expand Up @@ -713,6 +725,21 @@ public function testPositionalArgWithChoices(): void
$result = $parser->parse(['jose', 'coder'], $this->io);
}

/**
* test argument with default value.
*/
public function testPositionalArgumentWithDefault(): void
{
$parser = new ConsoleOptionParser('test', false);
$result = $parser->addArgument('name', ['help' => 'An argument', 'default' => 'foo']);

$result = $parser->parse(['bar'], $this->io);
$this->assertEquals(['bar'], $result[1], 'Got the correct value.');

$result = $parser->parse([], $this->io);
$this->assertEquals(['foo'], $result[1], 'Got the correct default value.');
}

/**
* Test adding multiple arguments.
*/
Expand Down Expand Up @@ -930,7 +957,7 @@ public function testHelpSubcommandInheritOptions(): void
])->addOption('connection', [
'help' => 'Db connection.',
'short' => 'c',
])->addArgument('name', ['required' => false]);
])->addArgument('name', ['required' => false, 'default' => 'foo']);

$result = $parser->help('build');
$expected = <<<TEXT
Expand All @@ -948,7 +975,7 @@ public function testHelpSubcommandInheritOptions(): void
<info>Arguments:</info>
name <comment>(optional)</comment>
name <comment>(optional)</comment> <comment>default: "foo"</comment>
TEXT;
$this->assertTextEquals($expected, $result, 'Help is not correct.');
Expand Down Expand Up @@ -1191,7 +1218,7 @@ public function testToArray(): void
$spec = [
'command' => 'test',
'arguments' => [
'name' => ['help' => 'The name'],
'name' => ['help' => 'The name', 'default' => 'foo'],
'other' => ['help' => 'The other arg'],
],
'options' => [
Expand Down
4 changes: 2 additions & 2 deletions tests/TestCase/Console/HelpFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ public function testXmlHelpWithChoices(): void
'choices' => ['aco', 'aro'],
'required' => true,
])
->addArgument('other_longer', ['help' => 'Another argument.']);
->addArgument('other_longer', ['help' => 'Another argument.', 'default' => 'foo']);

$formatter = new HelpFormatter($parser);
$result = $formatter->xml();
Expand Down Expand Up @@ -340,7 +340,7 @@ public function testXmlHelpWithChoices(): void
<choice>aro</choice>
</choices>
</argument>
<argument name="other_longer" help="Another argument." required="0">
<argument name="other_longer" help="Another argument." required="0" default="foo">
<choices></choices>
</argument>
</arguments>
Expand Down

0 comments on commit 335e01d

Please sign in to comment.