Skip to content

Commit

Permalink
Bind input before executing the COMMAND event
Browse files Browse the repository at this point in the history
  • Loading branch information
wouterj committed Sep 30, 2015
1 parent 58ed076 commit 0af1676
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/Symfony/Component/Console/Application.php
Expand Up @@ -13,6 +13,7 @@

use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Helper\DebugFormatterHelper;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Console\Helper\QuestionHelper;
Expand Down Expand Up @@ -880,6 +881,14 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
return $command->run($input, $output);
}

// bind before the console.command event, so the listeners have access to input options/arguments
try {
$command->mergeApplicationDefinition();
$input->bind($command->getDefinition());
} catch (ExceptionInterface $e) {
// ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
}

$event = new ConsoleCommandEvent($command, $input, $output);
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);

Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Component/Console/Command/Command.php
Expand Up @@ -13,6 +13,7 @@

use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
Expand Down Expand Up @@ -231,7 +232,7 @@ public function run(InputInterface $input, OutputInterface $output)
// bind the input against the command specific arguments/options
try {
$input->bind($this->definition);
} catch (\Exception $e) {
} catch (ExceptionInterface $e) {
if (!$this->ignoreValidationErrors) {
throw $e;
}
Expand Down
57 changes: 57 additions & 0 deletions src/Symfony/Component/Console/Tests/ApplicationTest.php
Expand Up @@ -943,6 +943,63 @@ public function testRunWithDispatcherSkippingCommand()
$this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode);
}

public function testRunWithDispatcherAccessingInputOptions()
{
$noInteractionValue = null;
$quietValue = null;

$dispatcher = $this->getDispatcher();
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$noInteractionValue, &$quietValue) {
$input = $event->getInput();

$noInteractionValue = $input->getOption('no-interaction');
$quietValue = $input->getOption('quiet');
});

$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);

$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo', '--no-interaction' => true));

$this->assertTrue($noInteractionValue);
$this->assertFalse($quietValue);
}

public function testRunWithDispatcherAddingInputOptions()
{
$extraValue = null;

$dispatcher = $this->getDispatcher();
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$extraValue) {
$definition = $event->getCommand()->getDefinition();
$input = $event->getInput();

$definition->addOption(new InputOption('extra', null, InputOption::VALUE_REQUIRED));
$input->bind($definition);

$extraValue = $input->getOption('extra');
});

$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);

$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo', '--extra' => 'some test value'));

$this->assertEquals('some test value', $extraValue);
}

public function testTerminalDimensions()
{
$application = new Application();
Expand Down

0 comments on commit 0af1676

Please sign in to comment.