bug #25407 [Console] Commands with an alias should not be recognized as ambiguous (Simperfit)

This PR was merged into the 2.7 branch.

Discussion
----------

[Console] Commands with an alias should not be recognized as ambiguous

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass?   | no
| Fixed tickets | no <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        |

When having two commands with the same starting name and an alias equal to the starting name, we should not have an ambiguous error because we are setting the alias.

Commits
-------

863f632 [Console] Commands with an alias should not be recognized as ambiguous
This commit is contained in:
Robin Chalas 2017-12-22 03:12:01 +01:00
commit 4bd9c79e93
4 changed files with 58 additions and 4 deletions

View File

@ -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));

View File

@ -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.

View File

@ -0,0 +1,21 @@
<?php
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TestTiti extends Command
{
protected function configure()
{
$this
->setName('test-titi')
->setDescription('The test:titi command')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->write('test-titi');
}
}

View File

@ -0,0 +1,22 @@
<?php
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TestToto extends Command
{
protected function configure()
{
$this
->setName('test-toto')
->setDescription('The test-toto command')
->setAliases(array('test'))
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->write('test-toto');
}
}