bug #21841 [Console] Do not squash input changes made from console.command event (chalasr)

This PR was merged into the 2.8 branch.

Discussion
----------

[Console] Do not squash input changes made from console.command event

| Q             | A
| ------------- | ---
| Branch?       | 2.8
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | https://github.com/symfony/symfony/issues/19441
| License       | MIT
| Doc PR        | n/a

Setting arguments/options from the `console.command` event is expected to work since https://github.com/symfony/symfony/pull/15938

Commits
-------

c8d364b721 [Console] Do not squash input changes made from console.command event
This commit is contained in:
Fabien Potencier 2017-03-05 12:03:23 -08:00
commit b8b6774634
3 changed files with 45 additions and 5 deletions

View File

@ -859,6 +859,10 @@ class Application
// ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
}
// don't bind the input again as it would override any input argument/option set from the command event in
// addition to being useless
$command->setInputBound(true);
$event = new ConsoleCommandEvent($command, $input, $output);
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);

View File

@ -42,6 +42,7 @@ class Command
private $ignoreValidationErrors = false;
private $applicationDefinitionMerged = false;
private $applicationDefinitionMergedWithArgs = false;
private $inputBound = false;
private $code;
private $synopsis = array();
private $usages = array();
@ -218,11 +219,13 @@ class Command
$this->mergeApplicationDefinition();
// bind the input against the command specific arguments/options
try {
$input->bind($this->definition);
} catch (ExceptionInterface $e) {
if (!$this->ignoreValidationErrors) {
throw $e;
if (!$this->inputBound) {
try {
$input->bind($this->definition);
} catch (ExceptionInterface $e) {
if (!$this->ignoreValidationErrors) {
throw $e;
}
}
}
@ -678,6 +681,14 @@ class Command
return $output->fetch();
}
/**
* @internal
*/
public function setInputBound($inputBound)
{
$this->inputBound = $inputBound;
}
/**
* Validates a command name.
*

View File

@ -1113,6 +1113,31 @@ class ApplicationTest extends TestCase
$this->assertEquals('some test value', $extraValue);
}
public function testUpdateInputFromConsoleCommandEvent()
{
$dispatcher = $this->getDispatcher();
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) {
$event->getInput()->setOption('extra', 'overriden');
});
$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);
$application
->register('foo')
->addOption('extra', null, InputOption::VALUE_REQUIRED)
->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
})
;
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo', '--extra' => 'original'));
$this->assertEquals('overriden', $tester->getInput()->getOption('extra'));
}
public function testTerminalDimensions()
{
$application = new Application();