Skip to content

Commit e9ad816

Browse files
committed
feature #60394 [Console][FrameworkBundle] Simplify using invokable commands when the component is used standalone (HypeMC)
This PR was merged into the 7.4 branch. Discussion ---------- [Console][FrameworkBundle] Simplify using invokable commands when the component is used standalone | Q | A | ------------- | --- | Branch? | 7.4 | Bug fix? | no | New feature? | yes | Deprecations? | yes | Issues | - | License | MIT Inspired by #60389 (comment) . This PR enables using invokable command when the component is used standalone: ```php #[AsCommand(name: 'app:example')] class ExampleCommand implements SignalableCommandInterface { public function __invoke(InputInterface $input, OutputInterface $output): int { // ... return Command::SUCCESS; } public function getSubscribedSignals(): array { return [\SIGINT, \SIGTERM]; } public function handleSignal(int $signal, int|false $previousExitCode = 0): int|false { // handle signal return 0; } } $application = new Application(); $application->addCommand(new ExampleCommand()); $application->run(); ``` Commits ------- 1886c10 [Console] Simplify using invokable commands when the component is used standalone
2 parents cd87bde + 1886c10 commit e9ad816

File tree

56 files changed

+442
-161
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+442
-161
lines changed

UPGRADE-7.4.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ Read more about this in the [Symfony documentation](https://symfony.com/doc/7.4/
88

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

11+
Console
12+
-------
13+
14+
* Deprecate `Symfony\Component\Console\Application::add()` in favor of `Symfony\Component\Console\Application::addCommand()`
15+
16+
FrameworkBundle
17+
---------------
18+
19+
* Deprecate `Symfony\Bundle\FrameworkBundle\Console\Application::add()` in favor of `Symfony\Bundle\FrameworkBundle\Console\Application::addCommand()`
20+
1121
HttpClient
1222
----------
1323

src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,12 @@ public function testComplete(array $input, array $expectedSuggestions)
304304
$environment = new Environment($loader);
305305

306306
$application = new Application();
307-
$application->add(new DebugCommand($environment, $projectDir, [], null, null));
307+
$command = new DebugCommand($environment, $projectDir, [], null, null);
308+
if (method_exists($application, 'addCommand')) {
309+
$application->addCommand($command);
310+
} else {
311+
$application->add($command);
312+
}
308313

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

341346
$application = new Application();
342-
$application->add(new DebugCommand($environment, $projectDir, $bundleMetadata, $defaultPath, null));
347+
$command = new DebugCommand($environment, $projectDir, $bundleMetadata, $defaultPath, null);
348+
if (method_exists($application, 'addCommand')) {
349+
$application->addCommand($command);
350+
} else {
351+
$application->add($command);
352+
}
343353
$command = $application->find('debug:twig');
344354

345355
return new CommandTester($command);

src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,11 @@ private function createCommand(): Command
179179
$command = new LintCommand($environment);
180180

181181
$application = new Application();
182-
$application->add($command);
182+
if (method_exists($application, 'addCommand')) {
183+
$application->addCommand($command);
184+
} else {
185+
$application->add($command);
186+
}
183187

184188
return $application->find('lint:twig');
185189
}

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.4
5+
---
6+
7+
* Deprecate `Symfony\Bundle\FrameworkBundle\Console\Application::add()` in favor of `Symfony\Bundle\FrameworkBundle\Console\Application::addCommand()`
8+
49
7.3
510
---
611

src/Symfony/Bundle/FrameworkBundle/Console/Application.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,29 @@ public function getLongVersion(): string
159159
return parent::getLongVersion().\sprintf(' (env: <comment>%s</>, debug: <comment>%s</>)', $this->kernel->getEnvironment(), $this->kernel->isDebug() ? 'true' : 'false');
160160
}
161161

162+
/**
163+
* @deprecated since Symfony 7.4, use Application::addCommand() instead
164+
*/
162165
public function add(Command $command): ?Command
166+
{
167+
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);
168+
169+
return $this->addCommand($command);
170+
}
171+
172+
public function addCommand(callable|Command $command): ?Command
163173
{
164174
$this->registerCommands();
165175

166-
return parent::add($command);
176+
if (!method_exists(BaseApplication::class, 'addCommand')) {
177+
if (!$command instanceof Command) {
178+
throw new \LogicException('Using callables as commands requires symfony/console 7.4 or higher.');
179+
}
180+
181+
return parent::add($command);
182+
}
183+
184+
return parent::addCommand($command);
167185
}
168186

169187
protected function registerCommands(): void
@@ -197,7 +215,7 @@ protected function registerCommands(): void
197215
foreach ($container->getParameter('console.command.ids') as $id) {
198216
if (!isset($lazyCommandIds[$id])) {
199217
try {
200-
$this->add($container->get($id));
218+
$this->addCommand($container->get($id));
201219
} catch (\Throwable $e) {
202220
$this->registrationErrors[] = $e;
203221
}

src/Symfony/Bundle/FrameworkBundle/Tests/Command/AboutCommand/AboutCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public function testAboutWithUnreadableFiles()
8282
private function createCommandTester(TestAppKernel $kernel): CommandTester
8383
{
8484
$application = new Application($kernel);
85-
$application->add(new AboutCommand());
85+
$application->addCommand(new AboutCommand());
8686

8787
return new CommandTester($application->find('about'));
8888
}

src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolClearCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ protected function setUp(): void
3636
public function testComplete(array $input, array $expectedSuggestions)
3737
{
3838
$application = new Application($this->getKernel());
39-
$application->add(new CachePoolClearCommand(new Psr6CacheClearer(['foo' => $this->cachePool]), ['foo']));
39+
$application->addCommand(new CachePoolClearCommand(new Psr6CacheClearer(['foo' => $this->cachePool]), ['foo']));
4040
$tester = new CommandCompletionTester($application->get('cache:pool:clear'));
4141

4242
$suggestions = $tester->complete($input);

src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolDeleteCommandTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function testCommandDeleteFailed()
9090
public function testComplete(array $input, array $expectedSuggestions)
9191
{
9292
$application = new Application($this->getKernel());
93-
$application->add(new CachePoolDeleteCommand(new Psr6CacheClearer(['foo' => $this->cachePool]), ['foo']));
93+
$application->addCommand(new CachePoolDeleteCommand(new Psr6CacheClearer(['foo' => $this->cachePool]), ['foo']));
9494
$tester = new CommandCompletionTester($application->get('cache:pool:delete'));
9595

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

130130
return new CommandTester($application->find('cache:pool:delete'));
131131
}

src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePruneCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private function getPruneableInterfaceMock(): MockObject&PruneableInterface
7777
private function getCommandTester(KernelInterface $kernel, RewindableGenerator $generator): CommandTester
7878
{
7979
$application = new Application($kernel);
80-
$application->add(new CachePoolPruneCommand($generator));
80+
$application->addCommand(new CachePoolPruneCommand($generator));
8181

8282
return new CommandTester($application->find('cache:pool:prune'));
8383
}

src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ public function testWithNotMatchPath()
4646
private function createCommandTester(): CommandTester
4747
{
4848
$application = new Application($this->getKernel());
49-
$application->add(new RouterMatchCommand($this->getRouter()));
50-
$application->add(new RouterDebugCommand($this->getRouter()));
49+
$application->addCommand(new RouterMatchCommand($this->getRouter()));
50+
$application->addCommand(new RouterDebugCommand($this->getRouter()));
5151

5252
return new CommandTester($application->find('router:match'));
5353
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy