From f12a4c1aee9796913b8fbe29fadf7a7340aa0a5f Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Thu, 13 Aug 2015 08:25:37 +0100 Subject: [PATCH 1/2] [Console] Fix input validation when required arguments are missing Previous rule was only working when arguments are passed from command line, as in command line there is no way of skipping an argument. The rule does not work for arguments set on the Input after a command is run. --- src/Symfony/Component/Console/Input/Input.php | 11 +++++++++-- .../Component/Console/Tests/Input/InputTest.php | 13 ++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Console/Input/Input.php b/src/Symfony/Component/Console/Input/Input.php index 05a029f09c..8103d19316 100644 --- a/src/Symfony/Component/Console/Input/Input.php +++ b/src/Symfony/Component/Console/Input/Input.php @@ -72,8 +72,15 @@ abstract class Input implements InputInterface */ 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/Input/InputTest.php b/src/Symfony/Component/Console/Tests/Input/InputTest.php index 0b3e38fb6f..eb1c6617f5 100644 --- a/src/Symfony/Component/Console/Tests/Input/InputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/InputTest.php @@ -94,7 +94,7 @@ class InputTest extends \PHPUnit_Framework_TestCase /** * @expectedException \RuntimeException - * @expectedExceptionMessage Not enough arguments. + * @expectedExceptionMessage Not enough arguments (missing: "name"). */ public function testValidateWithMissingArguments() { @@ -103,6 +103,17 @@ class InputTest extends \PHPUnit_Framework_TestCase $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')); From 4982b02bdd15fdf2046f426bd108bb3679bee65c Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Tue, 15 Sep 2015 08:23:21 +0100 Subject: [PATCH 2/2] [Console] Add the command name to input arguments if it's missing --- src/Symfony/Component/Console/Command/Command.php | 7 +++++++ .../Component/Console/Tests/Command/CommandTest.php | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index f169b6eb87..bccbc2ff4b 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -241,6 +241,13 @@ class Command $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/Tests/Command/CommandTest.php b/src/Symfony/Component/Console/Tests/Command/CommandTest.php index a0c8d78deb..a252fe7127 100644 --- a/src/Symfony/Component/Console/Tests/Command/CommandTest.php +++ b/src/Symfony/Component/Console/Tests/Command/CommandTest.php @@ -267,6 +267,15 @@ class CommandTest extends \PHPUnit_Framework_TestCase $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();