[Console] Allow commands to provide a default name for compile time registration

This commit is contained in:
Robin Chalas 2017-08-16 21:44:58 +02:00
parent aef502b1a2
commit 5d9ae6b56f
4 changed files with 71 additions and 2 deletions

View File

@ -7,6 +7,7 @@ CHANGELOG
* added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
`ContainerCommandLoader` for commands lazy-loading
* added a case-insensitive command name matching fallback
* added `DefaultNameProviderInterface`
3.3.0
-----

View File

@ -0,0 +1,26 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Command;
/**
* Enables lazy-loading capabilities for a Command by exposing its default name.
*
* @author Nicolas Grekas <p@tchwork.com>
* @author Robin Chalas <robin.chalas@gmail.com>
*/
interface DefaultNameProviderInterface
{
/**
* @return string The name to use by default for calling the Command
*/
public static function getDefaultName();
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Console\DependencyInjection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\DefaultNameProviderInterface;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
@ -55,7 +56,7 @@ class AddConsoleCommandPass implements CompilerPassInterface
$commandId = 'console.command.'.strtolower(str_replace('\\', '_', $class));
if (!isset($tags[0]['command'])) {
if (!isset($tags[0]['command']) && !$r->implementsInterface(DefaultNameProviderInterface::class)) {
if (isset($serviceIds[$commandId]) || $container->hasAlias($commandId)) {
$commandId = $commandId.'_'.$id;
}
@ -69,7 +70,7 @@ class AddConsoleCommandPass implements CompilerPassInterface
}
$serviceIds[$commandId] = false;
$commandName = $tags[0]['command'];
$commandName = isset($tags[0]['command']) ? $tags[0]['command'] : $class::getDefaultName();
unset($tags[0]);
$lazyCommandMap[$commandName] = $id;
$lazyCommandRefs[$id] = new TypedReference($id, $class);

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Console\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\DefaultNameProviderInterface;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
use Symfony\Component\Console\Command\Command;
@ -77,6 +78,38 @@ class AddConsoleCommandPassTest extends TestCase
$this->assertSame(array(array('setName', array('my:command')), array('setAliases', array(array('my:alias')))), $command->getMethodCalls());
}
public function testProcessFallsBackToDefaultName()
{
$container = new ContainerBuilder();
$container
->register('with-default-name', NamedCommand::class)
->setPublic(false)
->addTag('console.command')
;
$pass = new AddConsoleCommandPass();
$pass->process($container);
$commandLoader = $container->getDefinition('console.command_loader');
$commandLocator = $container->getDefinition((string) $commandLoader->getArgument(0));
$this->assertSame(ContainerCommandLoader::class, $commandLoader->getClass());
$this->assertSame(array('default' => 'with-default-name'), $commandLoader->getArgument(1));
$this->assertEquals(array(array('with-default-name' => new ServiceClosureArgument(new TypedReference('with-default-name', NamedCommand::class)))), $commandLocator->getArguments());
$this->assertSame(array('console.command.symfony_component_console_tests_dependencyinjection_namedcommand' => false), $container->getParameter('console.command.ids'));
$container = new ContainerBuilder();
$container
->register('with-default-name', NamedCommand::class)
->setPublic(false)
->addTag('console.command', array('command' => 'new-name'))
;
$pass->process($container);
$this->assertSame(array('new-name' => 'with-default-name'), $container->getDefinition('console.command_loader')->getArgument(1));
}
public function visibilityProvider()
{
return array(
@ -146,3 +179,11 @@ class AddConsoleCommandPassTest extends TestCase
class MyCommand extends Command
{
}
class NamedCommand extends Command implements DefaultNameProviderInterface
{
public static function getDefaultName()
{
return 'default';
}
}