-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
Symfony version(s) affected: symfony/console, (at least) 4.1
Description
When not giving a value to an option with VALUE_OPTIONAL, one would expect the option to gain the default value; instead, the option value is null.
How to reproduce
<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
class CommandOptionDefaultValueTest extends TestCase
{
public function testCommandDefaultValueForOptionalOptionValues()
{
self::assertSame(
0,
(new Command())->setName('test')
->addOption(
'option',
'o',
InputOption::VALUE_OPTIONAL,
'Optional option!',
'This should be the default value...'
)
->setCode(function(InputInterface $input): int {
if ($input->getOption('option') === null) {
throw new \InvalidArgumentException(
'...but instead, the default became `null`!'
);
}
return 0;
})
->run(new StringInput('--option'), new NullOutput())
);
}
}Possible Solution
Use the available default value when an optional value is not provided.
Additional context
The current behaviour is potentially problematic, especially for options with a "true-ish" default value: When providing options such as dry-run or only-validated with a default value of true, one would expect that running: command --dry-run will make a dry run, and command --only-validated will only process the validated data.
This assumption is exceptionally easily made when the option explicitly declares its default value to be true.
What happens in reality, however, is the following:
- the option value is missing, thus becoming
null - the if-statement (eg.
if ($input->getOption('dry-run'))) considers null to be false command --dry-rundoes not make a dry run- hell breaks loose
Note: When not adding the option at all, the default value is used as expected.