Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Console][FrameworkBundle] Simplify using invokable commands when the component is used standalone #60394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions UPGRADE-7.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ Read more about this in the [Symfony documentation](https://symfony.com/doc/7.4/

If you're upgrading from a version below 7.3, follow the [7.3 upgrade guide](UPGRADE-7.3.md) first.

Console
-------

* Deprecate `Symfony\Component\Console\Application::add()` in favor of `Symfony\Component\Console\Application::addCommand()`

FrameworkBundle
---------------

* Deprecate `Symfony\Bundle\FrameworkBundle\Console\Application::add()` in favor of `Symfony\Bundle\FrameworkBundle\Console\Application::addCommand()`

HttpClient
----------

Expand Down
14 changes: 12 additions & 2 deletions src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,12 @@ public function testComplete(array $input, array $expectedSuggestions)
$environment = new Environment($loader);

$application = new Application();
$application->add(new DebugCommand($environment, $projectDir, [], null, null));
$command = new DebugCommand($environment, $projectDir, [], null, null);
if (method_exists($application, 'addCommand')) {
$application->addCommand($command);
} else {
$application->add($command);
}

$tester = new CommandCompletionTester($application->find('debug:twig'));
$suggestions = $tester->complete($input, 2);
Expand Down Expand Up @@ -339,7 +344,12 @@ private function createCommandTester(array $paths = [], array $bundleMetadata =
}

$application = new Application();
$application->add(new DebugCommand($environment, $projectDir, $bundleMetadata, $defaultPath, null));
$command = new DebugCommand($environment, $projectDir, $bundleMetadata, $defaultPath, null);
if (method_exists($application, 'addCommand')) {
$application->addCommand($command);
} else {
$application->add($command);
}
$command = $application->find('debug:twig');

return new CommandTester($command);
Expand Down
6 changes: 5 additions & 1 deletion src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,11 @@ private function createCommand(): Command
$command = new LintCommand($environment);

$application = new Application();
$application->add($command);
if (method_exists($application, 'addCommand')) {
$application->addCommand($command);
} else {
$application->add($command);
}

return $application->find('lint:twig');
}
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

7.4
---

* Deprecate `Symfony\Bundle\FrameworkBundle\Console\Application::add()` in favor of `Symfony\Bundle\FrameworkBundle\Console\Application::addCommand()`

7.3
---

Expand Down
22 changes: 20 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,29 @@ public function getLongVersion(): string
return parent::getLongVersion().\sprintf(' (env: <comment>%s</>, debug: <comment>%s</>)', $this->kernel->getEnvironment(), $this->kernel->isDebug() ? 'true' : 'false');
}

/**
* @deprecated since Symfony 7.4, use Application::addCommand() instead
*/
public function add(Command $command): ?Command
{
trigger_deprecation('symfony/framework-bundle', '7.4', 'The "%s()" method is deprecated and will be removed in Symfony 8.0, use "%s::addCommand()" instead.', __METHOD__, self::class);

return $this->addCommand($command);
}

public function addCommand(callable|Command $command): ?Command
{
$this->registerCommands();

return parent::add($command);
if (!method_exists(BaseApplication::class, 'addCommand')) {
if (!$command instanceof Command) {
throw new \LogicException('Using callables as commands requires symfony/console 7.4 or higher.');
}

return parent::add($command);
}

return parent::addCommand($command);
}

protected function registerCommands(): void
Expand Down Expand Up @@ -197,7 +215,7 @@ protected function registerCommands(): void
foreach ($container->getParameter('console.command.ids') as $id) {
if (!isset($lazyCommandIds[$id])) {
try {
$this->add($container->get($id));
$this->addCommand($container->get($id));
} catch (\Throwable $e) {
$this->registrationErrors[] = $e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function testAboutWithUnreadableFiles()
private function createCommandTester(TestAppKernel $kernel): CommandTester
{
$application = new Application($kernel);
$application->add(new AboutCommand());
$application->addCommand(new AboutCommand());

return new CommandTester($application->find('about'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected function setUp(): void
public function testComplete(array $input, array $expectedSuggestions)
{
$application = new Application($this->getKernel());
$application->add(new CachePoolClearCommand(new Psr6CacheClearer(['foo' => $this->cachePool]), ['foo']));
$application->addCommand(new CachePoolClearCommand(new Psr6CacheClearer(['foo' => $this->cachePool]), ['foo']));
$tester = new CommandCompletionTester($application->get('cache:pool:clear'));

$suggestions = $tester->complete($input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function testCommandDeleteFailed()
public function testComplete(array $input, array $expectedSuggestions)
{
$application = new Application($this->getKernel());
$application->add(new CachePoolDeleteCommand(new Psr6CacheClearer(['foo' => $this->cachePool]), ['foo']));
$application->addCommand(new CachePoolDeleteCommand(new Psr6CacheClearer(['foo' => $this->cachePool]), ['foo']));
$tester = new CommandCompletionTester($application->get('cache:pool:delete'));

$suggestions = $tester->complete($input);
Expand Down Expand Up @@ -125,7 +125,7 @@ private function getKernel(): MockObject&KernelInterface
private function getCommandTester(KernelInterface $kernel): CommandTester
{
$application = new Application($kernel);
$application->add(new CachePoolDeleteCommand(new Psr6CacheClearer(['foo' => $this->cachePool])));
$application->addCommand(new CachePoolDeleteCommand(new Psr6CacheClearer(['foo' => $this->cachePool])));

return new CommandTester($application->find('cache:pool:delete'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private function getPruneableInterfaceMock(): MockObject&PruneableInterface
private function getCommandTester(KernelInterface $kernel, RewindableGenerator $generator): CommandTester
{
$application = new Application($kernel);
$application->add(new CachePoolPruneCommand($generator));
$application->addCommand(new CachePoolPruneCommand($generator));

return new CommandTester($application->find('cache:pool:prune'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public function testWithNotMatchPath()
private function createCommandTester(): CommandTester
{
$application = new Application($this->getKernel());
$application->add(new RouterMatchCommand($this->getRouter()));
$application->add(new RouterDebugCommand($this->getRouter()));
$application->addCommand(new RouterMatchCommand($this->getRouter()));
$application->addCommand(new RouterDebugCommand($this->getRouter()));

return new CommandTester($application->find('router:match'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ function ($path, $catalogue) use ($loadedMessages) {
$command = new TranslationDebugCommand($translator, $loader, $extractor, $this->translationDir.'/translations', $this->translationDir.'/templates', $transPaths, $codePaths, $enabledLocales);

$application = new Application($kernel);
$application->add($command);
$application->addCommand($command);

return $application->find('debug:translation');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function ($path, $catalogue) use ($loadedMessages) {
$command = new TranslationExtractCommand($writer, $loader, $extractor, 'en', $this->translationDir.'/translations', $this->translationDir.'/templates', $transPaths, $codePaths, ['en', 'fr']);

$application = new Application($kernel);
$application->add($command);
$application->addCommand($command);

return new CommandCompletionTester($application->find('translation:extract'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ function (MessageCatalogue $catalogue) use ($writerMessages) {
$command = new TranslationExtractCommand($writer, $loader, $extractor, 'en', $this->translationDir.'/translations', $this->translationDir.'/templates', $transPaths, $codePaths);

$application = new Application($kernel);
$application->add($command);
$application->addCommand($command);

return new CommandTester($application->find('translation:extract'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ class WorkflowDumpCommandTest extends TestCase
public function testComplete(array $input, array $expectedSuggestions)
{
$application = new Application();
$application->add(new WorkflowDumpCommand(new ServiceLocator([])));
$command = new WorkflowDumpCommand(new ServiceLocator([]));
if (method_exists($application, 'addCommand')) {
$application->addCommand($command);
} else {
$application->add($command);
}

$tester = new CommandCompletionTester($application->find('workflow:dump'));
$suggestions = $tester->complete($input, 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ private function createCommandTester($application = null): CommandTester
{
if (!$application) {
$application = new BaseApplication();
$application->add(new XliffLintCommand());
$command = new XliffLintCommand();
if (method_exists($application, 'addCommand')) {
$application->addCommand($command);
} else {
$application->add($command);
}
}

$command = $application->find('lint:xliff');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,12 @@ private function createCommandTester($application = null): CommandTester
{
if (!$application) {
$application = new BaseApplication();
$application->add(new YamlLintCommand());
$command = new YamlLintCommand();
if (method_exists($application, 'addCommand')) {
$application->addCommand($command);
} else {
$application->add($command);
}
}

$command = $application->find('lint:yaml');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public function testBundleCommandCanOverriddeAPreExistingCommandWithTheSameName(

$application = new Application($kernel);
$newCommand = new Command('example');
$application->add($newCommand);
$application->addCommand($newCommand);

$this->assertSame($newCommand, $application->get('example'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function testBundlePublicDir()
$fs = new Filesystem();
$fs->remove($projectDir);
$fs->mkdir($projectDir.'/public');
$command = (new Application($kernel))->add(new AssetsInstallCommand($fs, $projectDir));
$command = (new Application($kernel))->addCommand(new AssetsInstallCommand($fs, $projectDir));
$exitCode = (new CommandTester($command))->execute(['target' => $projectDir.'/public']);

$this->assertSame(0, $exitCode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public function testExcludedPool()
private function createCommandTester(?array $poolNames = null)
{
$application = new Application(static::$kernel);
$application->add(new CachePoolClearCommand(static::getContainer()->get('cache.global_clearer'), $poolNames));
$application->addCommand(new CachePoolClearCommand(static::getContainer()->get('cache.global_clearer'), $poolNames));

return new CommandTester($application->find('cache:pool:clear'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function testEmptyList()
private function createCommandTester(array $poolNames)
{
$application = new Application(static::$kernel);
$application->add(new CachePoolListCommand($poolNames));
$application->addCommand(new CachePoolListCommand($poolNames));

return new CommandTester($application->find('cache:pool:list'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public function testComplete(bool $debug, array $input, array $expectedSuggestio
{
$application = $this->createApplication($debug);

$application->add(new ConfigDebugCommand());
$application->addCommand(new ConfigDebugCommand());
$tester = new CommandCompletionTester($application->get('debug:config'));
$suggestions = $tester->complete($input);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public function testComplete(bool $debug, array $input, array $expectedSuggestio
{
$application = $this->createApplication($debug);

$application->add(new ConfigDumpReferenceCommand());
$application->addCommand(new ConfigDumpReferenceCommand());
$tester = new CommandCompletionTester($application->get('config:dump-reference'));
$suggestions = $tester->complete($input);
$this->assertSame($expectedSuggestions, $suggestions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public function testNotConfusedByClassAliases()
public function testComplete(array $input, array $expectedSuggestions)
{
$kernel = static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml']);
$command = (new Application($kernel))->add(new DebugAutowiringCommand());
$command = (new Application($kernel))->addCommand(new DebugAutowiringCommand());

$tester = new CommandCompletionTester($command);

Expand Down
39 changes: 33 additions & 6 deletions src/Symfony/Component/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\Console;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\CompleteCommand;
use Symfony\Component\Console\Command\DumpCompletionCommand;
Expand All @@ -28,6 +29,7 @@
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Exception\NamespaceNotFoundException;
use Symfony\Component\Console\Exception\RuntimeException;
Expand Down Expand Up @@ -512,33 +514,58 @@
*/
public function register(string $name): Command
{
return $this->add(new Command($name));
return $this->addCommand(new Command($name));

Check failure on line 517 in src/Symfony/Component/Console/Application.php

View workflow job for this annotation

GitHub Actions / Psalm

NullableReturnStatement

src/Symfony/Component/Console/Application.php:517:16: NullableReturnStatement: The declared return type 'Symfony\Component\Console\Command\Command' for Symfony\Component\Console\Application::register is not nullable, but the function returns 'Symfony\Component\Console\Command\Command|null' (see https://psalm.dev/139)

Check failure on line 517 in src/Symfony/Component/Console/Application.php

View workflow job for this annotation

GitHub Actions / Psalm

NullableReturnStatement

src/Symfony/Component/Console/Application.php:517:16: NullableReturnStatement: The declared return type 'Symfony\Component\Console\Command\Command' for Symfony\Component\Console\Application::register is not nullable, but the function returns 'Symfony\Component\Console\Command\Command|null' (see https://psalm.dev/139)
}

/**
* Adds an array of command objects.
*
* If a Command is not enabled it will not be added.
*
* @param Command[] $commands An array of commands
* @param callable[]|Command[] $commands An array of commands
*/
public function addCommands(array $commands): void
{
foreach ($commands as $command) {
$this->add($command);
$this->addCommand($command);
}
}

/**
* @deprecated since Symfony 7.4, use Application::addCommand() instead
*/
public function add(Command $command): ?Command
{
trigger_deprecation('symfony/console', '7.4', 'The "%s()" method is deprecated and will be removed in Symfony 8.0, use "%s::addCommand()" instead.', __METHOD__, self::class);

return $this->addCommand($command);
}

/**
* Adds a command object.
*
* If a command with the same name already exists, it will be overridden.
* If the command is not enabled it will not be added.
*/
public function add(Command $command): ?Command
public function addCommand(callable|Command $command): ?Command
{
$this->init();

if (!$command instanceof Command) {
if (!\is_object($command) || $command instanceof \Closure) {
throw new InvalidArgumentException(\sprintf('The command must be an instance of "%s" or an invokable object.', Command::class));
}

/** @var AsCommand $attribute */
$attribute = ((new \ReflectionObject($command))->getAttributes(AsCommand::class)[0] ?? null)?->newInstance()
?? throw new LogicException(\sprintf('The command must use the "%s" attribute.', AsCommand::class));

$command = (new Command($attribute->name))
->setDescription($attribute->description ?? '')
->setHelp($attribute->help ?? '')
->setCode($command);
}

$command->setApplication($this);

if (!$command->isEnabled()) {
Expand Down Expand Up @@ -604,7 +631,7 @@
{
$this->init();

return isset($this->commands[$name]) || ($this->commandLoader?->has($name) && $this->add($this->commandLoader->get($name)));
return isset($this->commands[$name]) || ($this->commandLoader?->has($name) && $this->addCommand($this->commandLoader->get($name)));
}

/**
Expand Down Expand Up @@ -1322,7 +1349,7 @@
$this->initialized = true;

foreach ($this->getDefaultCommands() as $command) {
$this->add($command);
$this->addCommand($command);
}
}
}
Loading
Loading