Skip to content

Commit c7f9137

Browse files
author
Robin Chalas
committed
[Console] Allow commands to provide a default name for compile time registration
1 parent 1a5acc9 commit c7f9137

File tree

4 files changed

+76
-2
lines changed

4 files changed

+76
-2
lines changed

src/Symfony/Component/Console/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
88
`ContainerCommandLoader` for commands lazy-loading
99
* added a case-insensitive command name matching fallback
10+
* added `DefaultNameProviderInterface`
1011

1112
3.3.0
1213
-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Console\Command;
13+
14+
/**
15+
* Enables lazy-loading capabilities for a Command by exposing its default name.
16+
*
17+
* @author Nicolas Grekas <p@tchwork.com>
18+
* @author Robin Chalas <robin.chalas@gmail.com>
19+
*/
20+
interface DefaultNameProviderInterface
21+
{
22+
/**
23+
* @return string The name to which register the implementing Command
24+
*/
25+
public static function getDefaultName();
26+
}

src/Symfony/Component/Console/DependencyInjection/AddConsoleCommandPass.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Console\DependencyInjection;
1313

1414
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Command\DefaultNameProviderInterface;
1516
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
1617
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1718
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
@@ -55,7 +56,7 @@ public function process(ContainerBuilder $container)
5556

5657
$commandId = 'console.command.'.strtolower(str_replace('\\', '_', $class));
5758

58-
if (!isset($tags[0]['command'])) {
59+
if (!isset($tags[0]['command']) && !$r->implementsInterface(DefaultNameProviderInterface::class)) {
5960
if (isset($serviceIds[$commandId]) || $container->hasAlias($commandId)) {
6061
$commandId = $commandId.'_'.$id;
6162
}
@@ -69,7 +70,12 @@ public function process(ContainerBuilder $container)
6970
}
7071

7172
$serviceIds[$commandId] = false;
72-
$commandName = $tags[0]['command'];
73+
if (!isset($tags[0]['command'])) {
74+
$defaultNameProvider = array($class, 'getDefaultName');
75+
$commandName = $defaultNameProvider();
76+
} else {
77+
$commandName = $tags[0]['command'];
78+
}
7379
unset($tags[0]);
7480
$lazyCommandMap[$commandName] = $id;
7581
$lazyCommandRefs[$id] = new TypedReference($id, $class);

src/Symfony/Component/Console/Tests/DependencyInjection/AddConsoleCommandPassTest.php

+41
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Console\Tests\DependencyInjection;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Console\Command\DefaultNameProviderInterface;
1516
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
1617
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
1718
use Symfony\Component\Console\Command\Command;
@@ -78,6 +79,38 @@ public function testProcessRegistersLazyCommands()
7879
$this->assertSame(array(array('setName', array('my:command')), array('setAliases', array(array('my:alias')))), $command->getMethodCalls());
7980
}
8081

82+
public function testProcessFallsBackToDefaultName()
83+
{
84+
$container = new ContainerBuilder();
85+
$container
86+
->register('with-default-name', NamedCommand::class)
87+
->setPublic(false)
88+
->addTag('console.command')
89+
;
90+
91+
$pass = new AddConsoleCommandPass();
92+
$pass->process($container);
93+
94+
$commandLoader = $container->getDefinition('console.command_loader');
95+
$commandLocator = $container->getDefinition((string) $commandLoader->getArgument(0));
96+
97+
$this->assertSame(ContainerCommandLoader::class, $commandLoader->getClass());
98+
$this->assertSame(array('default' => 'with-default-name'), $commandLoader->getArgument(1));
99+
$this->assertEquals(array(array('with-default-name' => new ServiceClosureArgument(new TypedReference('with-default-name', NamedCommand::class)))), $commandLocator->getArguments());
100+
$this->assertSame(array('console.command.symfony_component_console_tests_dependencyinjection_namedcommand' => false), $container->getParameter('console.command.ids'));
101+
102+
$container = new ContainerBuilder();
103+
$container
104+
->register('with-default-name', NamedCommand::class)
105+
->setPublic(false)
106+
->addTag('console.command', array('command' => 'new-name'))
107+
;
108+
109+
$pass->process($container);
110+
111+
$this->assertSame(array('new-name' => 'with-default-name'), $container->getDefinition('console.command_loader')->getArgument(1));
112+
}
113+
81114
public function visibilityProvider()
82115
{
83116
return array(
@@ -151,3 +184,11 @@ class MyCommand extends Command
151184
class ExtensionPresentBundle extends Bundle
152185
{
153186
}
187+
188+
class NamedCommand extends Command implements DefaultNameProviderInterface
189+
{
190+
public static function getDefaultName()
191+
{
192+
return 'default';
193+
}
194+
}

0 commit comments

Comments
 (0)