Skip to content

Commit

Permalink
[Console] Fix negated options not accessible
Browse files Browse the repository at this point in the history
  • Loading branch information
jderusse committed Jun 3, 2021
1 parent 198448e commit 7b9d373
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/Symfony/Component/Console/Input/Input.php
Expand Up @@ -146,10 +146,17 @@ public function getOptions()
*/
public function getOption(string $name)
{
if ($this->definition->hasNegation($name)) {
if (null === $value = $this->getOption($this->definition->negationToName($name))) {
return $value;
}

return !$value;
}

if (!$this->definition->hasOption($name)) {
throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
}

return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
}

Expand All @@ -158,7 +165,11 @@ public function getOption(string $name)
*/
public function setOption(string $name, $value)
{
if (!$this->definition->hasOption($name)) {
if ($this->definition->hasNegation($name)) {
$this->options[$this->definition->negationToName($name)] = !$value;

return;
} elseif (!$this->definition->hasOption($name)) {
throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
}

Expand All @@ -170,7 +181,7 @@ public function setOption(string $name, $value)
*/
public function hasOption(string $name)
{
return $this->definition->hasOption($name);
return $this->definition->hasOption($name) || $this->definition->hasNegation($name);
}

/**
Expand Down
14 changes: 14 additions & 0 deletions src/Symfony/Component/Console/Tests/Input/InputTest.php
Expand Up @@ -45,6 +45,20 @@ public function testOptions()
$input = new ArrayInput(['--name' => 'foo', '--bar' => null], new InputDefinition([new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default')]));
$this->assertNull($input->getOption('bar'), '->getOption() returns null for options explicitly passed without value (or an empty value)');
$this->assertEquals(['name' => 'foo', 'bar' => null], $input->getOptions(), '->getOptions() returns all option values');

$input = new ArrayInput(['--name' => null], new InputDefinition([new InputOption('name', null, InputOption::VALUE_NEGATABLE)]));
$this->assertTrue($input->hasOption('name'));
$this->assertTrue($input->hasOption('no-name'));
$this->assertTrue($input->getOption('name'));
$this->assertFalse($input->getOption('no-name'));

$input = new ArrayInput(['--no-name' => null], new InputDefinition([new InputOption('name', null, InputOption::VALUE_NEGATABLE)]));
$this->assertFalse($input->getOption('name'));
$this->assertTrue($input->getOption('no-name'));

$input = new ArrayInput([], new InputDefinition([new InputOption('name', null, InputOption::VALUE_NEGATABLE)]));
$this->assertNull($input->getOption('name'));
$this->assertNull($input->getOption('no-name'));
}

public function testSetInvalidOption()
Expand Down

0 comments on commit 7b9d373

Please sign in to comment.