bug #31261 [Console] Commands with an alias should not be recognized as ambiguous when using register (Simperfit)

This PR was merged into the 3.4 branch.

Discussion
----------

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

| Q             | A
| ------------- | ---
| Branch?       | 2.8
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #25355
| License       | MIT
| Doc PR        |

I think when passing an alias, it should not be treated as a ambiguous command since it's configured to response to it.

I've [pushed a commit](2f5209a687) that reproduce the bug and with this patch it does work.

Commits
-------

ae7ee46465 [Console] Commands with an alias should not be recognized as ambiguous
This commit is contained in:
Nicolas Grekas 2019-05-09 10:42:51 +02:00
commit fb4d92877f
4 changed files with 43 additions and 13 deletions

View File

@ -596,6 +596,15 @@ class Application
$this->init(); $this->init();
$aliases = []; $aliases = [];
foreach ($this->commands as $command) {
foreach ($command->getAliases() as $alias) {
if (!$this->has($alias)) {
$this->commands[$alias] = $command;
}
}
}
$allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands); $allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : 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);

View File

@ -72,8 +72,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.'/TestAmbiguousCommandRegistering.php';
require_once self::$fixturesPath.'/TestToto.php'; require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php';
} }
protected function normalizeLineBreaks($text) protected function normalizeLineBreaks($text)
@ -164,6 +164,27 @@ class ApplicationTest extends TestCase
$this->assertEquals('foo', $command->getName(), '->register() registers a new command'); $this->assertEquals('foo', $command->getName(), '->register() registers a new command');
} }
public function testRegisterAmbiguous()
{
$code = function (InputInterface $input, OutputInterface $output) {
$output->writeln('It works!');
};
$application = new Application();
$application
->register('test-foo')
->setAliases(['test'])
->setCode($code);
$application
->register('test-bar')
->setCode($code);
$tester = new ApplicationTester($application);
$tester->run(['test']);
$this->assertContains('It works!', $tester->getDisplay(true));
}
public function testAdd() public function testAdd()
{ {
$application = new Application(); $application = new Application();
@ -303,9 +324,9 @@ class ApplicationTest extends TestCase
public function testFindNonAmbiguous() public function testFindNonAmbiguous()
{ {
$application = new Application(); $application = new Application();
$application->add(new \TestTiti()); $application->add(new \TestAmbiguousCommandRegistering());
$application->add(new \TestToto()); $application->add(new \TestAmbiguousCommandRegistering2());
$this->assertEquals('test-toto', $application->find('test')->getName()); $this->assertEquals('test-ambiguous', $application->find('test')->getName());
} }
/** /**

View File

@ -4,19 +4,19 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
class TestToto extends Command class TestAmbiguousCommandRegistering extends Command
{ {
protected function configure() protected function configure()
{ {
$this $this
->setName('test-toto') ->setName('test-ambiguous')
->setDescription('The test-toto command') ->setDescription('The test-ambiguous command')
->setAliases(['test']) ->setAliases(['test'])
; ;
} }
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$output->write('test-toto'); $output->write('test-ambiguous');
} }
} }

View File

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