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:
commit
4bd9c79e93
|
@ -498,7 +498,7 @@ class Application
|
||||||
public function find($name)
|
public function find($name)
|
||||||
{
|
{
|
||||||
$this->init();
|
$this->init();
|
||||||
|
$aliases = array();
|
||||||
$allCommands = array_keys($this->commands);
|
$allCommands = array_keys($this->commands);
|
||||||
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
|
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
|
||||||
$commands = preg_grep('{^'.$expr.'}', $allCommands);
|
$commands = preg_grep('{^'.$expr.'}', $allCommands);
|
||||||
|
@ -526,15 +526,16 @@ class Application
|
||||||
// filter out aliases for commands which are already on the list
|
// filter out aliases for commands which are already on the list
|
||||||
if (count($commands) > 1) {
|
if (count($commands) > 1) {
|
||||||
$commandList = $this->commands;
|
$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();
|
$commandName = $commandList[$nameOrAlias]->getName();
|
||||||
|
$aliases[$nameOrAlias] = $commandName;
|
||||||
|
|
||||||
return $commandName === $nameOrAlias || !in_array($commandName, $commands);
|
return $commandName === $nameOrAlias || !in_array($commandName, $commands);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$exact = in_array($name, $commands, true);
|
$exact = in_array($name, $commands, true) || isset($aliases[$name]);
|
||||||
if (count($commands) > 1 && !$exact) {
|
if (!$exact && count($commands) > 1) {
|
||||||
$suggestions = $this->getAbbreviationSuggestions(array_values($commands));
|
$suggestions = $this->getAbbreviationSuggestions(array_values($commands));
|
||||||
|
|
||||||
throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions));
|
throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions));
|
||||||
|
|
|
@ -49,6 +49,8 @@ class ApplicationTest extends TestCase
|
||||||
require_once self::$fixturesPath.'/BarBucCommand.php';
|
require_once self::$fixturesPath.'/BarBucCommand.php';
|
||||||
require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
|
require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
|
||||||
require_once self::$fixturesPath.'/FooSubnamespaced2Command.php';
|
require_once self::$fixturesPath.'/FooSubnamespaced2Command.php';
|
||||||
|
require_once self::$fixturesPath.'/TestTiti.php';
|
||||||
|
require_once self::$fixturesPath.'/TestToto.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function normalizeLineBreaks($text)
|
protected function normalizeLineBreaks($text)
|
||||||
|
@ -226,6 +228,14 @@ class ApplicationTest extends TestCase
|
||||||
$application->findNamespace('f');
|
$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
|
* @expectedException \InvalidArgumentException
|
||||||
* @expectedExceptionMessage There are no commands defined in the "bar" namespace.
|
* @expectedExceptionMessage There are no commands defined in the "bar" namespace.
|
||||||
|
|
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue