diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 6ab9f011ac..53460d2de2 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -498,7 +498,7 @@ class Application public function find($name) { $this->init(); - + $aliases = array(); $allCommands = array_keys($this->commands); $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name); $commands = preg_grep('{^'.$expr.'}', $allCommands); @@ -526,15 +526,16 @@ class Application // filter out aliases for commands which are already on the list if (count($commands) > 1) { $commandList = $this->commands; - $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) { + $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands, &$aliases) { $commandName = $commandList[$nameOrAlias]->getName(); + $aliases[$nameOrAlias] = $commandName; return $commandName === $nameOrAlias || !in_array($commandName, $commands); }); } - $exact = in_array($name, $commands, true); - if (count($commands) > 1 && !$exact) { + $exact = in_array($name, $commands, true) || isset($aliases[$name]); + if (!$exact && count($commands) > 1) { $suggestions = $this->getAbbreviationSuggestions(array_values($commands)); throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 8ffc5d6951..5ab3b0a598 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -49,6 +49,8 @@ class ApplicationTest extends TestCase require_once self::$fixturesPath.'/BarBucCommand.php'; require_once self::$fixturesPath.'/FooSubnamespaced1Command.php'; require_once self::$fixturesPath.'/FooSubnamespaced2Command.php'; + require_once self::$fixturesPath.'/TestTiti.php'; + require_once self::$fixturesPath.'/TestToto.php'; } protected function normalizeLineBreaks($text) @@ -226,6 +228,14 @@ class ApplicationTest extends TestCase $application->findNamespace('f'); } + public function testFindNonAmbiguous() + { + $application = new Application(); + $application->add(new \TestTiti()); + $application->add(new \TestToto()); + $this->assertEquals('test-toto', $application->find('test')->getName()); + } + /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage There are no commands defined in the "bar" namespace. diff --git a/src/Symfony/Component/Console/Tests/Fixtures/TestTiti.php b/src/Symfony/Component/Console/Tests/Fixtures/TestTiti.php new file mode 100644 index 0000000000..72e29d2a0a --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/TestTiti.php @@ -0,0 +1,21 @@ +setName('test-titi') + ->setDescription('The test:titi command') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->write('test-titi'); + } +} diff --git a/src/Symfony/Component/Console/Tests/Fixtures/TestToto.php b/src/Symfony/Component/Console/Tests/Fixtures/TestToto.php new file mode 100644 index 0000000000..f14805db68 --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/TestToto.php @@ -0,0 +1,22 @@ +setName('test-toto') + ->setDescription('The test-toto command') + ->setAliases(array('test')) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->write('test-toto'); + } +}