From 71d0be14f5da823db7af4202f84d061ae19cb065 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Thu, 9 Jan 2025 08:13:51 -0500 Subject: [PATCH] [Console] Invokable command deprecations --- UPGRADE-7.3.md | 22 +++++++++++++++++++ src/Symfony/Component/Console/CHANGELOG.md | 4 ++-- .../Component/Console/Command/Command.php | 2 +- .../Console/Command/InvokableCommand.php | 19 +++++++++++----- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/UPGRADE-7.3.md b/UPGRADE-7.3.md index bbfc42348b7a2..61f69a3acf377 100644 --- a/UPGRADE-7.3.md +++ b/UPGRADE-7.3.md @@ -8,6 +8,28 @@ Read more about this in the [Symfony documentation](https://symfony.com/doc/7.3/ If you're upgrading from a version below 7.1, follow the [7.2 upgrade guide](UPGRADE-7.2.md) first. +Console +------- + + * Omitting parameter types in callables configured via `Command::setCode` method is deprecated + + *Before* + ```php + $command->setCode(function ($input, $output) { + // ... + }); + ``` + + *After* + ```php + use Symfony\Component\Console\Input\InputInterface; + use Symfony\Component\Console\Output\OutputInterface; + + $command->setCode(function (InputInterface $input, OutputInterface $output) { + // ... + }); + ``` + FrameworkBundle --------------- diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index a8837b528a0db..c37f4f100c96c 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -4,8 +4,8 @@ CHANGELOG 7.3 --- -* Add support for invokable commands -* Add `#[Argument]` and `#[Option]` attributes to define input arguments and options for invokable commands + * Add support for invokable commands and add `#[Argument]` and `#[Option]` attributes to define input arguments and options + * Deprecate not declaring the parameter type in callable commands defined through `setCode` method 7.2 --- diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index 27d0651fae60c..b9664371abdc4 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -328,7 +328,7 @@ public function setCode(callable $code): static $code = $code(...); } - $this->code = new InvokableCommand($this, $code); + $this->code = new InvokableCommand($this, $code, triggerDeprecations: true); return $this; } diff --git a/src/Symfony/Component/Console/Command/InvokableCommand.php b/src/Symfony/Component/Console/Command/InvokableCommand.php index 6c7136fda60d3..ccdbd057985ec 100644 --- a/src/Symfony/Component/Console/Command/InvokableCommand.php +++ b/src/Symfony/Component/Console/Command/InvokableCommand.php @@ -35,6 +35,7 @@ class InvokableCommand public function __construct( private readonly Command $command, private readonly \Closure $code, + private readonly bool $triggerDeprecations = false, ) { $this->reflection = new \ReflectionFunction($code); } @@ -47,10 +48,13 @@ public function __invoke(InputInterface $input, OutputInterface $output): int $statusCode = ($this->code)(...$this->getParameters($input, $output)); if (null !== $statusCode && !\is_int($statusCode)) { - // throw new LogicException(\sprintf('The command "%s" must return either void or an integer value in the "%s" method, but "%s" was returned.', $this->command->getName(), $this->reflection->getName(), get_debug_type($statusCode))); - trigger_deprecation('symfony/console', '7.3', \sprintf('Returning a non-integer value from the command "%s" is deprecated and will throw an exception in PHP 8.0.', $this->command->getName())); + if ($this->triggerDeprecations) { + trigger_deprecation('symfony/console', '7.3', \sprintf('Returning a non-integer value from the command "%s" is deprecated and will throw an exception in PHP 8.0.', $this->command->getName())); - return 0; + return 0; + } + + throw new LogicException(\sprintf('The command "%s" must return either void or an integer value in the "%s" method, but "%s" was returned.', $this->command->getName(), $this->reflection->getName(), get_debug_type($statusCode))); } return $statusCode ?? 0; @@ -92,10 +96,13 @@ private function getParameters(InputInterface $input, OutputInterface $output): $type = $parameter->getType(); if (!$type instanceof \ReflectionNamedType) { - // throw new LogicException(\sprintf('The parameter "$%s" must have a named type. Untyped, Union or Intersection types are not supported.', $parameter->getName())); - trigger_deprecation('symfony/console', '7.3', \sprintf('Omitting the type declaration for the parameter "$%s" is deprecated and will throw an exception in PHP 8.0.', $parameter->getName())); + if ($this->triggerDeprecations) { + trigger_deprecation('symfony/console', '7.3', \sprintf('Omitting the type declaration for the parameter "$%s" is deprecated and will throw an exception in PHP 8.0.', $parameter->getName())); - continue; + continue; + } + + throw new LogicException(\sprintf('The parameter "$%s" must have a named type. Untyped, Union or Intersection types are not supported.', $parameter->getName())); } $parameters[] = match ($type->getName()) {