diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index f169b6eb8702e..bccbc2ff4b8cf 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -241,6 +241,13 @@ public function run(InputInterface $input, OutputInterface $output) $this->interact($input, $output); } + // The command name argument is often omitted when a command is executed directly with its run() method. + // It would fail the validation if we didn't make sure the command argument is present, + // since it's required by the application. + if ($input->hasArgument('command') && null === $input->getArgument('command')) { + $input->setArgument('command', $this->getName()); + } + $input->validate(); if ($this->code) { diff --git a/src/Symfony/Component/Console/Input/Input.php b/src/Symfony/Component/Console/Input/Input.php index 05a029f09caaf..8103d193164c2 100644 --- a/src/Symfony/Component/Console/Input/Input.php +++ b/src/Symfony/Component/Console/Input/Input.php @@ -72,8 +72,15 @@ abstract protected function parse(); */ public function validate() { - if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) { - throw new \RuntimeException('Not enough arguments.'); + $definition = $this->definition; + $givenArguments = $this->arguments; + + $missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) { + return !array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired(); + }); + + if (count($missingArguments) > 0) { + throw new \RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments))); } } diff --git a/src/Symfony/Component/Console/Tests/Command/CommandTest.php b/src/Symfony/Component/Console/Tests/Command/CommandTest.php index a0c8d78deb275..a252fe7127794 100644 --- a/src/Symfony/Component/Console/Tests/Command/CommandTest.php +++ b/src/Symfony/Component/Console/Tests/Command/CommandTest.php @@ -267,6 +267,15 @@ public function testRunReturnsIntegerExitCode() $this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)'); } + public function testRunWithApplication() + { + $command = new \TestCommand(); + $command->setApplication(new Application()); + $exitCode = $command->run(new StringInput(''), new NullOutput()); + + $this->assertSame(0, $exitCode, '->run() returns an integer exit code'); + } + public function testRunReturnsAlwaysInteger() { $command = new \TestCommand(); diff --git a/src/Symfony/Component/Console/Tests/Input/InputTest.php b/src/Symfony/Component/Console/Tests/Input/InputTest.php index 0b3e38fb6f4ce..eb1c6617f5644 100644 --- a/src/Symfony/Component/Console/Tests/Input/InputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/InputTest.php @@ -94,7 +94,7 @@ public function testGetInvalidArgument() /** * @expectedException \RuntimeException - * @expectedExceptionMessage Not enough arguments. + * @expectedExceptionMessage Not enough arguments (missing: "name"). */ public function testValidateWithMissingArguments() { @@ -103,6 +103,17 @@ public function testValidateWithMissingArguments() $input->validate(); } + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Not enough arguments (missing: "name"). + */ + public function testValidateWithMissingRequiredArguments() + { + $input = new ArrayInput(array('bar' => 'baz')); + $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED), new InputArgument('bar', InputArgument::OPTIONAL)))); + $input->validate(); + } + public function testValidate() { $input = new ArrayInput(array('name' => 'foo'));
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: