From 3563589fa00d678680ff1ec953bb7e06299bd7d9 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 1 Aug 2026 12:11:53 +0200 Subject: [PATCH 1/2] [composer-based] Bond version-specific rules to composer package constraints Add config/sets/symfony/composer-based.php, a single set holding rules bound to the exact Symfony package version their target API was added in, mirroring the rector-phpunit composer-based set. Each rule declares its own constraint via ComposerPackageConstraintInterface, so it is registered once here instead of being repeated in every Symfony version set to cover a direct upgrade from an older version. Symfony has no single package to trigger on, so every package used inside the set registers it as a ComposerTriggeredSet, from the lowest version its rules require. Existing sets stay untouched. --- composer.json | 3 + config/sets/symfony/composer-based.php | 84 +++++++++++++++++++ ...tionSecurityAttributeToIsGrantedRector.php | 9 +- ...tAndSecurityAttributeToIsGrantedRector.php | 9 +- ...fonyStringToConstructorInjectionRector.php | 3 +- .../Rector/New_/RootNodeTreeBuilderRector.php | 9 +- .../StringToArrayArgumentProcessRector.php | 9 +- .../EventDispatcherParentConstructRector.php | 9 +- .../MakeDispatchFirstArgumentEventRector.php | 9 +- .../ConsoleExecuteReturnIntRector.php | 9 +- .../CommandConstantReturnCodeRector.php | 9 +- ...utHandlerToLogoutEventSubscriberRector.php | 9 +- ...ssHandlerToLogoutEventSubscriberRector.php | 9 +- ...nitionAliasSetPrivateToSetPublicRector.php | 9 +- ...xtractorEnableMagicCallExtractorRector.php | 9 +- ...orBuilderEnableAnnotationMappingRector.php | 9 +- ...tyAccessorCreationBooleanToFlagsRector.php | 9 +- ...yFileResponseCreateToNewInstanceRector.php | 9 +- .../GetHelperControllerToServiceRector.php | 5 +- ...sureTwigExtensionToNativeMethodsRector.php | 9 +- .../ErrorNamesPropertyToConstantRector.php | 9 +- ...mentValueResolverToValueResolverRector.php | 9 +- ...terAttributeToMapEntityAttributeRector.php | 9 +- ...ssageHandlerInterfaceToAttributeRector.php | 9 +- ...geSubscriberInterfaceToAttributeRector.php | 9 +- ...ityAttributeToIsGrantedAttributeRector.php | 9 +- .../Class_/ParamAndEnvAttributeRector.php | 9 +- ...alableCommandInterfaceReturnTypeRector.php | 9 +- src/Set/SetProvider/SymfonySetProvider.php | 46 ++++++++++ 29 files changed, 330 insertions(+), 27 deletions(-) create mode 100644 config/sets/symfony/composer-based.php diff --git a/composer.json b/composer.json index 2cec7d1d2..7ac2f9723 100644 --- a/composer.json +++ b/composer.json @@ -18,10 +18,13 @@ "rector/swiss-knife": "^2.4", "symfony/config": "^8.1", "symfony/dependency-injection": "^6.4", + "symfony/doctrine-bridge": "^6.4", "symfony/http-kernel": "^7.4", + "symfony/messenger": "^6.4", "symfony/routing": "^6.4", "symfony/security-core": "^6.4", "symfony/security-http": "^6.4", + "symfony/twig-bridge": "^6.4", "symfony/validator": "^6.4", "symfony/web-link": "^6.4", "symplify/easy-coding-standard": "^13.2", diff --git a/config/sets/symfony/composer-based.php b/config/sets/symfony/composer-based.php new file mode 100644 index 000000000..5e94e5243 --- /dev/null +++ b/config/sets/symfony/composer-based.php @@ -0,0 +1,84 @@ +rules([ + // symfony/config 4.2 + RootNodeTreeBuilderRector::class, + + // symfony/process 4.2 + StringToArrayArgumentProcessRector::class, + + // symfony/event-dispatcher 4.3 + MakeDispatchFirstArgumentEventRector::class, + EventDispatcherParentConstructRector::class, + + // symfony/console 4.4 and 5.1 + ConsoleExecuteReturnIntRector::class, + CommandConstantReturnCodeRector::class, + + // symfony/security-http 5.1 + LogoutHandlerToLogoutEventSubscriberRector::class, + LogoutSuccessHandlerToLogoutEventSubscriberRector::class, + + // symfony/* 5.2 + DefinitionAliasSetPrivateToSetPublicRector::class, + ReflectionExtractorEnableMagicCallExtractorRector::class, + ValidatorBuilderEnableAnnotationMappingRector::class, + PropertyAccessorCreationBooleanToFlagsRector::class, + BinaryFileResponseCreateToNewInstanceRector::class, + + // symfony/twig-bridge and symfony/validator 6.1 + MagicClosureTwigExtensionToNativeMethodsRector::class, + ErrorNamesPropertyToConstantRector::class, + + // attributes added in Symfony 6.2 + MessageHandlerInterfaceToAttributeRector::class, + MessageSubscriberInterfaceToAttributeRector::class, + SecurityAttributeToIsGrantedAttributeRector::class, + SingleConditionSecurityAttributeToIsGrantedRector::class, + SplitAndSecurityAttributeToIsGrantedRector::class, + ParamConverterAttributeToMapEntityAttributeRector::class, + ArgumentValueResolverToValueResolverRector::class, + + // symfony/dependency-injection and symfony/console 6.3 + ParamAndEnvAttributeRector::class, + SignalableCommandInterfaceReturnTypeRector::class, + ]); +}; diff --git a/rules/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector.php b/rules/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector.php index a6a163a28..7b1d2d910 100644 --- a/rules/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector.php +++ b/rules/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector.php @@ -13,6 +13,8 @@ use Rector\Rector\AbstractRector; use Rector\Symfony\CodeQuality\NodeAnalyzer\AttributePresenceDetector; use Rector\Symfony\Enum\SensioAttribute; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -22,13 +24,18 @@ * * @see \Rector\Symfony\Tests\CodeQuality\Rector\AttributeGroup\SingleConditionSecurityAttributeToIsGrantedRector\SingleConditionSecurityAttributeToIsGrantedRectorTest */ -final class SingleConditionSecurityAttributeToIsGrantedRector extends AbstractRector +final class SingleConditionSecurityAttributeToIsGrantedRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly AttributePresenceDetector $attributePresenceDetector, ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/security-http', '>=6.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector.php b/rules/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector.php index c702c0228..9a0befc45 100644 --- a/rules/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector.php +++ b/rules/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector.php @@ -14,6 +14,8 @@ use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -22,8 +24,13 @@ /** * @see \Rector\Symfony\Tests\CodeQuality\Rector\Class_\SplitAndSecurityAttributeToIsGrantedRector\SplitAndSecurityAttributeToIsGrantedRectorTest */ -final class SplitAndSecurityAttributeToIsGrantedRector extends AbstractRector +final class SplitAndSecurityAttributeToIsGrantedRector extends AbstractRector implements ComposerPackageConstraintInterface { + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/security-http', '>=6.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php b/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php index f7df11327..f02ba22c3 100644 --- a/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php +++ b/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php @@ -4,6 +4,7 @@ namespace Rector\Symfony\DependencyInjection\Rector\Class_; +use Doctrine\Persistence\ManagerRegistry; use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Stmt\Class_; @@ -42,7 +43,7 @@ final class GetBySymfonyStringToConstructorInjectionRector extends AbstractRecto 'security.authorization_checker' => 'Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface', 'templating' => 'Symfony\Component\Templating\EngineInterface', 'twig' => 'Twig\Environment', - 'doctrine' => 'Doctrine\Persistence\ManagerRegistry', + 'doctrine' => ManagerRegistry::class, 'form.factory' => 'Symfony\Component\Form\FormFactoryInterface', 'security.csrf.token_manager' => 'Symfony\Component\Security\Core\Authorization\CsrfTokenManagerInterface', 'parameter_bag' => 'Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface', diff --git a/rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php b/rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php index 00b4052f3..11ee08279 100644 --- a/rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php +++ b/rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php @@ -15,6 +15,8 @@ use Rector\PhpParser\Enum\NodeGroup; use Rector\PhpParser\Node\BetterNodeFinder; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -23,13 +25,18 @@ * * @see \Rector\Symfony\Tests\Symfony42\Rector\New_\RootNodeTreeBuilderRector\RootNodeTreeBuilderRectorTest */ -final class RootNodeTreeBuilderRector extends AbstractRector +final class RootNodeTreeBuilderRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly BetterNodeFinder $betterNodeFinder ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/config', '>=4.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony42/Rector/New_/StringToArrayArgumentProcessRector.php b/rules/Symfony42/Rector/New_/StringToArrayArgumentProcessRector.php index e6bd5f3e7..c6c646802 100644 --- a/rules/Symfony42/Rector/New_/StringToArrayArgumentProcessRector.php +++ b/rules/Symfony42/Rector/New_/StringToArrayArgumentProcessRector.php @@ -18,6 +18,8 @@ use Rector\PhpParser\NodeTransformer; use Rector\Rector\AbstractRector; use Rector\Util\Reflection\PrivatesAccessor; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symfony\Component\Console\Input\StringInput; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -27,7 +29,7 @@ * * @see \Rector\Symfony\Tests\Symfony42\Rector\New_\StringToArrayArgumentProcessRector\StringToArrayArgumentProcessRectorTest */ -final class StringToArrayArgumentProcessRector extends AbstractRector +final class StringToArrayArgumentProcessRector extends AbstractRector implements ComposerPackageConstraintInterface { /** * @var string[] @@ -44,6 +46,11 @@ public function __construct( ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/process', '>=4.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony43/Rector/ClassMethod/EventDispatcherParentConstructRector.php b/rules/Symfony43/Rector/ClassMethod/EventDispatcherParentConstructRector.php index cde7f2945..3dc80943f 100644 --- a/rules/Symfony43/Rector/ClassMethod/EventDispatcherParentConstructRector.php +++ b/rules/Symfony43/Rector/ClassMethod/EventDispatcherParentConstructRector.php @@ -14,19 +14,26 @@ use Rector\PHPStan\ScopeFetcher; use Rector\Rector\AbstractRector; use Rector\ValueObject\MethodName; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @see \Rector\Symfony\Tests\Symfony43\Rector\ClassMethod\EventDispatcherParentConstructRector\EventDispatcherParentConstructRectorTest */ -final class EventDispatcherParentConstructRector extends AbstractRector +final class EventDispatcherParentConstructRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly BetterNodeFinder $betterNodeFinder ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/event-dispatcher', '>=4.3'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony43/Rector/MethodCall/MakeDispatchFirstArgumentEventRector.php b/rules/Symfony43/Rector/MethodCall/MakeDispatchFirstArgumentEventRector.php index 22499f078..5094074f5 100644 --- a/rules/Symfony43/Rector/MethodCall/MakeDispatchFirstArgumentEventRector.php +++ b/rules/Symfony43/Rector/MethodCall/MakeDispatchFirstArgumentEventRector.php @@ -14,6 +14,8 @@ use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -22,7 +24,7 @@ * * @see \Rector\Symfony\Tests\Symfony43\Rector\MethodCall\MakeDispatchFirstArgumentEventRector\MakeDispatchFirstArgumentEventRectorTest */ -final class MakeDispatchFirstArgumentEventRector extends AbstractRector +final class MakeDispatchFirstArgumentEventRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly StringTypeAnalyzer $stringTypeAnalyzer, @@ -30,6 +32,11 @@ public function __construct( ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/event-dispatcher', '>=4.3'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony44/Rector/ClassMethod/ConsoleExecuteReturnIntRector.php b/rules/Symfony44/Rector/ClassMethod/ConsoleExecuteReturnIntRector.php index 3d8a76a39..9b9407d42 100644 --- a/rules/Symfony44/Rector/ClassMethod/ConsoleExecuteReturnIntRector.php +++ b/rules/Symfony44/Rector/ClassMethod/ConsoleExecuteReturnIntRector.php @@ -20,6 +20,8 @@ use Rector\NodeAnalyzer\TerminatedNodeAnalyzer; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -27,7 +29,7 @@ * @changelog https://github.com/symfony/symfony/pull/33775/files * @see \Rector\Symfony\Tests\Symfony44\Rector\ClassMethod\ConsoleExecuteReturnIntRector\ConsoleExecuteReturnIntRectorTest */ -final class ConsoleExecuteReturnIntRector extends AbstractRector +final class ConsoleExecuteReturnIntRector extends AbstractRector implements ComposerPackageConstraintInterface { private bool $hasChanged = false; @@ -37,6 +39,11 @@ public function __construct( ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/console', '>=4.4'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Returns int from Command::execute() command', [ diff --git a/rules/Symfony51/Rector/ClassMethod/CommandConstantReturnCodeRector.php b/rules/Symfony51/Rector/ClassMethod/CommandConstantReturnCodeRector.php index f7be15b83..5eba872d4 100644 --- a/rules/Symfony51/Rector/ClassMethod/CommandConstantReturnCodeRector.php +++ b/rules/Symfony51/Rector/ClassMethod/CommandConstantReturnCodeRector.php @@ -15,6 +15,8 @@ use Rector\Reflection\ReflectionResolver; use Rector\Symfony\Enum\SymfonyClass; use Rector\Symfony\ValueObject\ConstantMap\SymfonyCommandConstantMap; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -23,7 +25,7 @@ * * @see \Rector\Symfony\Tests\Symfony51\Rector\ClassMethod\CommandConstantReturnCodeRector\CommandConstantReturnCodeRectorTest */ -final class CommandConstantReturnCodeRector extends AbstractRector +final class CommandConstantReturnCodeRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly ReflectionResolver $reflectionResolver, @@ -31,6 +33,11 @@ public function __construct( ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/console', '>=5.1'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony51/Rector/Class_/LogoutHandlerToLogoutEventSubscriberRector.php b/rules/Symfony51/Rector/Class_/LogoutHandlerToLogoutEventSubscriberRector.php index 1e982b22e..b64fd2bd3 100644 --- a/rules/Symfony51/Rector/Class_/LogoutHandlerToLogoutEventSubscriberRector.php +++ b/rules/Symfony51/Rector/Class_/LogoutHandlerToLogoutEventSubscriberRector.php @@ -14,6 +14,8 @@ use Rector\Symfony\NodeFactory\GetSubscribedEventsClassMethodFactory; use Rector\Symfony\NodeFactory\OnLogoutClassMethodFactory; use Rector\Symfony\ValueObject\EventReferenceToMethodName; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -22,7 +24,7 @@ * * @see \Rector\Symfony\Tests\Symfony51\Rector\Class_\LogoutHandlerToLogoutEventSubscriberRector\LogoutHandlerToLogoutEventSubscriberRectorTest */ -final class LogoutHandlerToLogoutEventSubscriberRector extends AbstractRector +final class LogoutHandlerToLogoutEventSubscriberRector extends AbstractRector implements ComposerPackageConstraintInterface { private readonly ObjectType $logoutHandlerObjectType; @@ -33,6 +35,11 @@ public function __construct( $this->logoutHandlerObjectType = new ObjectType(SymfonyClass::LOGOUT_HANDLER_INTERFACE); } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/security-http', '>=5.1'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Change logout handler to an event listener that listens to LogoutEvent', [ diff --git a/rules/Symfony51/Rector/Class_/LogoutSuccessHandlerToLogoutEventSubscriberRector.php b/rules/Symfony51/Rector/Class_/LogoutSuccessHandlerToLogoutEventSubscriberRector.php index 0368bfe40..c27267c54 100644 --- a/rules/Symfony51/Rector/Class_/LogoutSuccessHandlerToLogoutEventSubscriberRector.php +++ b/rules/Symfony51/Rector/Class_/LogoutSuccessHandlerToLogoutEventSubscriberRector.php @@ -15,6 +15,8 @@ use Rector\Symfony\NodeFactory\GetSubscribedEventsClassMethodFactory; use Rector\Symfony\NodeFactory\OnSuccessLogoutClassMethodFactory; use Rector\Symfony\ValueObject\EventReferenceToMethodNameWithPriority; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -23,7 +25,7 @@ * * @see \Rector\Symfony\Tests\Symfony51\Rector\Class_\LogoutSuccessHandlerToLogoutEventSubscriberRector\LogoutSuccessHandlerToLogoutEventSubscriberRectorTest */ -final class LogoutSuccessHandlerToLogoutEventSubscriberRector extends AbstractRector +final class LogoutSuccessHandlerToLogoutEventSubscriberRector extends AbstractRector implements ComposerPackageConstraintInterface { private readonly ObjectType $successHandlerObjectType; @@ -35,6 +37,11 @@ public function __construct( $this->successHandlerObjectType = new ObjectType(SymfonyClass::LOGOUT_SUCCESS_HANDLER); } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/security-http', '>=5.1'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Change logout success handler to an event listener that listens to LogoutEvent', [ diff --git a/rules/Symfony52/Rector/MethodCall/DefinitionAliasSetPrivateToSetPublicRector.php b/rules/Symfony52/Rector/MethodCall/DefinitionAliasSetPrivateToSetPublicRector.php index 488a0556c..63cc6cafc 100644 --- a/rules/Symfony52/Rector/MethodCall/DefinitionAliasSetPrivateToSetPublicRector.php +++ b/rules/Symfony52/Rector/MethodCall/DefinitionAliasSetPrivateToSetPublicRector.php @@ -11,6 +11,8 @@ use PHPStan\Type\ObjectType; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -18,7 +20,7 @@ * @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#dependencyinjection * @see \Rector\Symfony\Tests\Symfony52\Rector\MethodCall\DefinitionAliasSetPrivateToSetPublicRector\DefinitionAliasSetPrivateToSetPublicRectorTest */ -final class DefinitionAliasSetPrivateToSetPublicRector extends AbstractRector +final class DefinitionAliasSetPrivateToSetPublicRector extends AbstractRector implements ComposerPackageConstraintInterface { /** * @var ObjectType[] @@ -34,6 +36,11 @@ public function __construct( ]; } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/dependency-injection', '>=5.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony52/Rector/MethodCall/ReflectionExtractorEnableMagicCallExtractorRector.php b/rules/Symfony52/Rector/MethodCall/ReflectionExtractorEnableMagicCallExtractorRector.php index 3f5dfcded..32beae871 100644 --- a/rules/Symfony52/Rector/MethodCall/ReflectionExtractorEnableMagicCallExtractorRector.php +++ b/rules/Symfony52/Rector/MethodCall/ReflectionExtractorEnableMagicCallExtractorRector.php @@ -14,6 +14,8 @@ use PHPStan\Type\ObjectType; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -21,7 +23,7 @@ * @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyinfo * @see \Rector\Symfony\Tests\Symfony52\Rector\MethodCall\ReflectionExtractorEnableMagicCallExtractorRector\ReflectionExtractorEnableMagicCallExtractorRectorTest */ -final class ReflectionExtractorEnableMagicCallExtractorRector extends AbstractRector +final class ReflectionExtractorEnableMagicCallExtractorRector extends AbstractRector implements ComposerPackageConstraintInterface { private const string OLD_OPTION_NAME = 'enable_magic_call_extraction'; @@ -37,6 +39,11 @@ public function __construct( ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/property-info', '>=5.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony52/Rector/MethodCall/ValidatorBuilderEnableAnnotationMappingRector.php b/rules/Symfony52/Rector/MethodCall/ValidatorBuilderEnableAnnotationMappingRector.php index 43e8b43d3..3172d5f73 100644 --- a/rules/Symfony52/Rector/MethodCall/ValidatorBuilderEnableAnnotationMappingRector.php +++ b/rules/Symfony52/Rector/MethodCall/ValidatorBuilderEnableAnnotationMappingRector.php @@ -10,6 +10,8 @@ use PHPStan\Type\ObjectType; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -17,13 +19,18 @@ * @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#validator * @see \Rector\Symfony\Tests\Symfony52\Rector\MethodCall\ValidatorBuilderEnableAnnotationMappingRector\ValidatorBuilderEnableAnnotationMappingRectorTest */ -final class ValidatorBuilderEnableAnnotationMappingRector extends AbstractRector +final class ValidatorBuilderEnableAnnotationMappingRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly ValueResolver $valueResolver ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/validator', '>=5.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony52/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php b/rules/Symfony52/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php index 3e656cd3d..3f6c33bf8 100644 --- a/rules/Symfony52/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php +++ b/rules/Symfony52/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php @@ -11,6 +11,8 @@ use PhpParser\Node\Name; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -19,13 +21,18 @@ * * @see \Rector\Symfony\Tests\Symfony52\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector\PropertyAccessorCreationBooleanToFlagsRectorTest */ -final class PropertyAccessorCreationBooleanToFlagsRector extends AbstractRector +final class PropertyAccessorCreationBooleanToFlagsRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly ValueResolver $valueResolver ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/property-access', '>=5.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Changes first argument of PropertyAccessor::__construct() to flags from boolean', [ diff --git a/rules/Symfony52/Rector/StaticCall/BinaryFileResponseCreateToNewInstanceRector.php b/rules/Symfony52/Rector/StaticCall/BinaryFileResponseCreateToNewInstanceRector.php index 874efe1f4..a7efa1a29 100644 --- a/rules/Symfony52/Rector/StaticCall/BinaryFileResponseCreateToNewInstanceRector.php +++ b/rules/Symfony52/Rector/StaticCall/BinaryFileResponseCreateToNewInstanceRector.php @@ -9,6 +9,8 @@ use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Name; use Rector\Rector\AbstractRector; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -16,8 +18,13 @@ * @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#httpfoundation * @see \Rector\Symfony\Tests\Symfony52\Rector\StaticCall\BinaryFileResponseCreateToNewInstanceRector\BinaryFileResponseCreateToNewInstanceRectorTest */ -final class BinaryFileResponseCreateToNewInstanceRector extends AbstractRector +final class BinaryFileResponseCreateToNewInstanceRector extends AbstractRector implements ComposerPackageConstraintInterface { + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/http-foundation', '>=5.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Change deprecated BinaryFileResponse::create() to use __construct() instead', [ diff --git a/rules/Symfony60/Rector/MethodCall/GetHelperControllerToServiceRector.php b/rules/Symfony60/Rector/MethodCall/GetHelperControllerToServiceRector.php index 2744429dc..bbc4325f2 100644 --- a/rules/Symfony60/Rector/MethodCall/GetHelperControllerToServiceRector.php +++ b/rules/Symfony60/Rector/MethodCall/GetHelperControllerToServiceRector.php @@ -4,6 +4,7 @@ namespace Rector\Symfony\Symfony60\Rector\MethodCall; +use Doctrine\Persistence\ManagerRegistry; use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\PropertyFetch; @@ -149,10 +150,10 @@ private function createMessageBusPropertyMetadata(): PropertyMetadata private function createManagerRegistryPropertyMetadata(): PropertyMetadata { - $propertyName = $this->propertyNaming->fqnToVariableName('Doctrine\Persistence\ManagerRegistry'); + $propertyName = $this->propertyNaming->fqnToVariableName(ManagerRegistry::class); // add dependency - $propertyObjectType = new ObjectType('Doctrine\Persistence\ManagerRegistry'); + $propertyObjectType = new ObjectType(ManagerRegistry::class); return new PropertyMetadata($propertyName, $propertyObjectType); } } diff --git a/rules/Symfony61/Rector/Class_/MagicClosureTwigExtensionToNativeMethodsRector.php b/rules/Symfony61/Rector/Class_/MagicClosureTwigExtensionToNativeMethodsRector.php index 1d5d8e5b9..569764677 100644 --- a/rules/Symfony61/Rector/Class_/MagicClosureTwigExtensionToNativeMethodsRector.php +++ b/rules/Symfony61/Rector/Class_/MagicClosureTwigExtensionToNativeMethodsRector.php @@ -20,7 +20,9 @@ use Rector\Rector\AbstractRector; use Rector\Symfony\Enum\TwigClass; use Rector\ValueObject\PhpVersion; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -29,7 +31,7 @@ * * @see PHP 8.1 way to handle functions/filters https://github.com/symfony/symfony/blob/e0ad2eead3513a558c09d8aa3ae9e867fb10b419/src/Symfony/Bridge/Twig/Extension/CodeExtension.php#L41-L52 */ -final class MagicClosureTwigExtensionToNativeMethodsRector extends AbstractRector implements MinPhpVersionInterface +final class MagicClosureTwigExtensionToNativeMethodsRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface { public function __construct( private readonly ArrayCallableMethodMatcher $arrayCallableMethodMatcher, @@ -37,6 +39,11 @@ public function __construct( ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/twig-bridge', '>=6.1'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony61/Rector/StaticPropertyFetch/ErrorNamesPropertyToConstantRector.php b/rules/Symfony61/Rector/StaticPropertyFetch/ErrorNamesPropertyToConstantRector.php index d21373d72..9005f3219 100644 --- a/rules/Symfony61/Rector/StaticPropertyFetch/ErrorNamesPropertyToConstantRector.php +++ b/rules/Symfony61/Rector/StaticPropertyFetch/ErrorNamesPropertyToConstantRector.php @@ -16,6 +16,8 @@ use Rector\Rector\AbstractRector; use Rector\Reflection\ReflectionResolver; use Rector\Symfony\Enum\SymfonyClass; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -25,13 +27,18 @@ * * @see \Rector\Symfony\Tests\Symfony61\Rector\StaticPropertyFetch\ErrorNamesPropertyToConstantRector\ErrorNamesPropertyToConstantRectorTest */ -final class ErrorNamesPropertyToConstantRector extends AbstractRector +final class ErrorNamesPropertyToConstantRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly ReflectionResolver $reflectionResolver, ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/validator', '>=6.1'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony62/Rector/ClassMethod/ClassMethod/ArgumentValueResolverToValueResolverRector.php b/rules/Symfony62/Rector/ClassMethod/ClassMethod/ArgumentValueResolverToValueResolverRector.php index 28ecab1ad..7a45b1c30 100644 --- a/rules/Symfony62/Rector/ClassMethod/ClassMethod/ArgumentValueResolverToValueResolverRector.php +++ b/rules/Symfony62/Rector/ClassMethod/ClassMethod/ArgumentValueResolverToValueResolverRector.php @@ -18,13 +18,15 @@ use PhpParser\Node\Stmt\Return_; use Rector\Rector\AbstractRector; use Rector\Symfony\Enum\SymfonyClass; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @see \Rector\Symfony\Tests\Symfony62\Rector\ClassMethod\ArgumentValueResolverToValueResolverRector\ArgumentValueResolverToValueResolverRectorTest */ -final class ArgumentValueResolverToValueResolverRector extends AbstractRector +final class ArgumentValueResolverToValueResolverRector extends AbstractRector implements ComposerPackageConstraintInterface { public function getNodeTypes(): array { @@ -60,6 +62,11 @@ public function refactor(Node $node): ?Node return $node; } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/http-kernel', '>=6.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony62/Rector/ClassMethod/ParamConverterAttributeToMapEntityAttributeRector.php b/rules/Symfony62/Rector/ClassMethod/ParamConverterAttributeToMapEntityAttributeRector.php index c294985fb..26cb0d45a 100644 --- a/rules/Symfony62/Rector/ClassMethod/ParamConverterAttributeToMapEntityAttributeRector.php +++ b/rules/Symfony62/Rector/ClassMethod/ParamConverterAttributeToMapEntityAttributeRector.php @@ -20,7 +20,9 @@ use Rector\Symfony\Enum\SensioAttribute; use Rector\Symfony\Enum\SymfonyAnnotation; use Rector\ValueObject\PhpVersionFeature; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -29,13 +31,18 @@ * * @see \Rector\Symfony\Tests\Symfony62\Rector\ClassMethod\ParamConverterAttributeToMapEntityAttributeRector\ParamConverterAttributeToMapEntityAttributeRectorTest */ -final class ParamConverterAttributeToMapEntityAttributeRector extends AbstractRector implements MinPhpVersionInterface +final class ParamConverterAttributeToMapEntityAttributeRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface { public function provideMinPhpVersion(): int { return PhpVersionFeature::ATTRIBUTES; } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/doctrine-bridge', '>=6.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php b/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php index 7fc46d93a..74ba56b3c 100644 --- a/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php +++ b/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php @@ -14,14 +14,16 @@ use Rector\Symfony\NodeManipulator\ClassManipulator; use Rector\Symfony\ValueObject\ServiceDefinition; use Rector\ValueObject\PhpVersionFeature; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @see \Rector\Symfony\Tests\Symfony62\Rector\Class_\MessageHandlerInterfaceToAttributeRector\MessageHandlerToAttributeRectorTest */ -final class MessageHandlerInterfaceToAttributeRector extends AbstractRector implements MinPhpVersionInterface +final class MessageHandlerInterfaceToAttributeRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface { public function __construct( private readonly MessengerHelper $messengerHelper, @@ -36,6 +38,11 @@ public function provideMinPhpVersion(): int return PhpVersionFeature::ATTRIBUTES; } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/messenger', '>=6.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony62/Rector/Class_/MessageSubscriberInterfaceToAttributeRector.php b/rules/Symfony62/Rector/Class_/MessageSubscriberInterfaceToAttributeRector.php index 484807163..37132858b 100644 --- a/rules/Symfony62/Rector/Class_/MessageSubscriberInterfaceToAttributeRector.php +++ b/rules/Symfony62/Rector/Class_/MessageSubscriberInterfaceToAttributeRector.php @@ -20,14 +20,16 @@ use Rector\Symfony\NodeManipulator\ClassManipulator; use Rector\ValueObject\MethodName; use Rector\ValueObject\PhpVersionFeature; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @see \Rector\Symfony\Tests\Symfony62\Rector\Class_\MessageSubscriberInterfaceToAttributeRector\MessageSubscriberInterfaceToAttributeRectorTest */ -final class MessageSubscriberInterfaceToAttributeRector extends AbstractRector implements MinPhpVersionInterface +final class MessageSubscriberInterfaceToAttributeRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface { private string $newInvokeMethodName; @@ -44,6 +46,11 @@ public function provideMinPhpVersion(): int return PhpVersionFeature::ATTRIBUTES; } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/messenger', '>=6.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony62/Rector/Class_/SecurityAttributeToIsGrantedAttributeRector.php b/rules/Symfony62/Rector/Class_/SecurityAttributeToIsGrantedAttributeRector.php index 67b8b49ba..dd284260e 100644 --- a/rules/Symfony62/Rector/Class_/SecurityAttributeToIsGrantedAttributeRector.php +++ b/rules/Symfony62/Rector/Class_/SecurityAttributeToIsGrantedAttributeRector.php @@ -20,7 +20,9 @@ use Rector\Symfony\Enum\SensioAttribute; use Rector\Symfony\Enum\SymfonyAttribute; use Rector\ValueObject\PhpVersionFeature; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -30,7 +32,7 @@ * * @see \Rector\Symfony\Tests\Symfony62\Rector\Class_\SecurityAttributeToIsGrantedAttributeRector\SecurityAttributeToIsGrantedAttributeRectorTest */ -final class SecurityAttributeToIsGrantedAttributeRector extends AbstractRector implements MinPhpVersionInterface +final class SecurityAttributeToIsGrantedAttributeRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface { /** * @see https://regex101.com/r/Si1sDz/1 @@ -53,6 +55,11 @@ public function provideMinPhpVersion(): int return PhpVersionFeature::ATTRIBUTES; } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/security-http', '>=6.2'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony63/Rector/Class_/ParamAndEnvAttributeRector.php b/rules/Symfony63/Rector/Class_/ParamAndEnvAttributeRector.php index 5c0a5fcda..ea6d7f180 100644 --- a/rules/Symfony63/Rector/Class_/ParamAndEnvAttributeRector.php +++ b/rules/Symfony63/Rector/Class_/ParamAndEnvAttributeRector.php @@ -14,6 +14,8 @@ use Rector\Rector\AbstractRector; use Rector\Symfony\Enum\SymfonyAttribute; use Rector\ValueObject\MethodName; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -22,7 +24,7 @@ * * @see https://symfony.com/blog/new-in-symfony-6-3-dependency-injection-improvements#new-options-for-autowire-attribute */ -final class ParamAndEnvAttributeRector extends AbstractRector +final class ParamAndEnvAttributeRector extends AbstractRector implements ComposerPackageConstraintInterface { /** * @see https://regex101.com/r/7vwGbH/1 @@ -34,6 +36,11 @@ final class ParamAndEnvAttributeRector extends AbstractRector */ private const string ENV_REGEX = '#%env\((?\w+)\)%$#'; + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/dependency-injection', '>=6.3'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony63/Rector/Class_/SignalableCommandInterfaceReturnTypeRector.php b/rules/Symfony63/Rector/Class_/SignalableCommandInterfaceReturnTypeRector.php index 9c844af46..c68fd21a4 100644 --- a/rules/Symfony63/Rector/Class_/SignalableCommandInterfaceReturnTypeRector.php +++ b/rules/Symfony63/Rector/Class_/SignalableCommandInterfaceReturnTypeRector.php @@ -16,13 +16,15 @@ use Rector\StaticTypeMapper\StaticTypeMapper; use Rector\Symfony\NodeAnalyzer\ClassAnalyzer; use Rector\VendorLocker\ParentClassMethodTypeOverrideGuard; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @see \Rector\Symfony\Tests\Symfony63\Rector\Class_\SignalableCommandInterfaceReturnTypeRector\SignalableCommandInterfaceReturnTypeRectorTest */ -final class SignalableCommandInterfaceReturnTypeRector extends AbstractRector +final class SignalableCommandInterfaceReturnTypeRector extends AbstractRector implements ComposerPackageConstraintInterface { public function __construct( private readonly ClassAnalyzer $classAnalyzer, @@ -31,6 +33,11 @@ public function __construct( ) { } + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('symfony/console', '>=6.3'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/src/Set/SetProvider/SymfonySetProvider.php b/src/Set/SetProvider/SymfonySetProvider.php index 81ef43e5d..e47675b8b 100644 --- a/src/Set/SetProvider/SymfonySetProvider.php +++ b/src/Set/SetProvider/SymfonySetProvider.php @@ -7,16 +7,43 @@ use Rector\Set\Contract\SetInterface; use Rector\Set\Contract\SetProviderInterface; use Rector\Set\Enum\SetGroup; +use Rector\Set\ValueObject\ComposerTriggeredSet; use Rector\Set\ValueObject\Set; final class SymfonySetProvider implements SetProviderInterface { + /** + * The composer-based set holds rules bound to the exact Symfony package version they are available from. + * Symfony has no single package to trigger on, so every package used inside the set triggers it, + * from the lowest version its rules require. + * + * @var array + */ + private const array COMPOSER_BASED_TRIGGER_PACKAGES = [ + 'symfony/config' => '>=4.2', + 'symfony/process' => '>=4.2', + 'symfony/event-dispatcher' => '>=4.3', + 'symfony/console' => '>=4.4', + 'symfony/security-http' => '>=5.1', + 'symfony/dependency-injection' => '>=5.2', + 'symfony/http-foundation' => '>=5.2', + 'symfony/property-access' => '>=5.2', + 'symfony/property-info' => '>=5.2', + 'symfony/validator' => '>=5.2', + 'symfony/twig-bridge' => '>=6.1', + 'symfony/doctrine-bridge' => '>=6.2', + 'symfony/http-kernel' => '>=6.2', + 'symfony/messenger' => '>=6.2', + ]; + /** * @return SetInterface[] */ public function provide(): array { return [ + ...$this->provideComposerBasedSets(), + new Set(SetGroup::SYMFONY, 'Configs', __DIR__ . '/../../../config/sets/symfony/configs.php'), new Set( SetGroup::SYMFONY, @@ -60,4 +87,23 @@ public function provide(): array ), ]; } + + /** + * @return ComposerTriggeredSet[] + */ + private function provideComposerBasedSets(): array + { + $composerTriggeredSets = []; + + foreach (self::COMPOSER_BASED_TRIGGER_PACKAGES as $packageName => $version) { + $composerTriggeredSets[] = new ComposerTriggeredSet( + SetGroup::SYMFONY, + $packageName, + $version, + __DIR__ . '/../../../config/sets/symfony/composer-based.php' + ); + } + + return $composerTriggeredSets; + } } From 007ba4e001d8f23f9be055eb97d5a05fcc7249a6 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 1 Aug 2026 12:42:59 +0200 Subject: [PATCH 2/2] Drop rules that would require new dev dependencies Bonding a rule to a package only works when that package is installed, otherwise its test silently stops transforming. Keep composer.json as is and bond only rules whose package is already a dev dependency. Removes the symfony/messenger, symfony/twig-bridge and symfony/doctrine-bridge rules from the composer-based set. --- composer.json | 3 --- config/sets/symfony/composer-based.php | 10 +--------- .../GetBySymfonyStringToConstructorInjectionRector.php | 3 +-- .../MethodCall/GetHelperControllerToServiceRector.php | 5 ++--- .../MagicClosureTwigExtensionToNativeMethodsRector.php | 9 +-------- ...ramConverterAttributeToMapEntityAttributeRector.php | 9 +-------- .../MessageHandlerInterfaceToAttributeRector.php | 9 +-------- .../MessageSubscriberInterfaceToAttributeRector.php | 9 +-------- src/Set/SetProvider/SymfonySetProvider.php | 3 --- 9 files changed, 8 insertions(+), 52 deletions(-) diff --git a/composer.json b/composer.json index 7ac2f9723..2cec7d1d2 100644 --- a/composer.json +++ b/composer.json @@ -18,13 +18,10 @@ "rector/swiss-knife": "^2.4", "symfony/config": "^8.1", "symfony/dependency-injection": "^6.4", - "symfony/doctrine-bridge": "^6.4", "symfony/http-kernel": "^7.4", - "symfony/messenger": "^6.4", "symfony/routing": "^6.4", "symfony/security-core": "^6.4", "symfony/security-http": "^6.4", - "symfony/twig-bridge": "^6.4", "symfony/validator": "^6.4", "symfony/web-link": "^6.4", "symplify/easy-coding-standard": "^13.2", diff --git a/config/sets/symfony/composer-based.php b/config/sets/symfony/composer-based.php index 5e94e5243..a3fc308ba 100644 --- a/config/sets/symfony/composer-based.php +++ b/config/sets/symfony/composer-based.php @@ -18,13 +18,9 @@ use Rector\Symfony\Symfony52\Rector\MethodCall\ValidatorBuilderEnableAnnotationMappingRector; use Rector\Symfony\Symfony52\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector; use Rector\Symfony\Symfony52\Rector\StaticCall\BinaryFileResponseCreateToNewInstanceRector; -use Rector\Symfony\Symfony61\Rector\Class_\MagicClosureTwigExtensionToNativeMethodsRector; use Rector\Symfony\Symfony61\Rector\StaticPropertyFetch\ErrorNamesPropertyToConstantRector; -use Rector\Symfony\Symfony62\Rector\Class_\MessageHandlerInterfaceToAttributeRector; -use Rector\Symfony\Symfony62\Rector\Class_\MessageSubscriberInterfaceToAttributeRector; use Rector\Symfony\Symfony62\Rector\Class_\SecurityAttributeToIsGrantedAttributeRector; use Rector\Symfony\Symfony62\Rector\ClassMethod\ClassMethod\ArgumentValueResolverToValueResolverRector; -use Rector\Symfony\Symfony62\Rector\ClassMethod\ParamConverterAttributeToMapEntityAttributeRector; use Rector\Symfony\Symfony63\Rector\Class_\ParamAndEnvAttributeRector; use Rector\Symfony\Symfony63\Rector\Class_\SignalableCommandInterfaceReturnTypeRector; @@ -64,17 +60,13 @@ PropertyAccessorCreationBooleanToFlagsRector::class, BinaryFileResponseCreateToNewInstanceRector::class, - // symfony/twig-bridge and symfony/validator 6.1 - MagicClosureTwigExtensionToNativeMethodsRector::class, + // symfony/validator 6.1 ErrorNamesPropertyToConstantRector::class, // attributes added in Symfony 6.2 - MessageHandlerInterfaceToAttributeRector::class, - MessageSubscriberInterfaceToAttributeRector::class, SecurityAttributeToIsGrantedAttributeRector::class, SingleConditionSecurityAttributeToIsGrantedRector::class, SplitAndSecurityAttributeToIsGrantedRector::class, - ParamConverterAttributeToMapEntityAttributeRector::class, ArgumentValueResolverToValueResolverRector::class, // symfony/dependency-injection and symfony/console 6.3 diff --git a/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php b/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php index f02ba22c3..f7df11327 100644 --- a/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php +++ b/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php @@ -4,7 +4,6 @@ namespace Rector\Symfony\DependencyInjection\Rector\Class_; -use Doctrine\Persistence\ManagerRegistry; use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Stmt\Class_; @@ -43,7 +42,7 @@ final class GetBySymfonyStringToConstructorInjectionRector extends AbstractRecto 'security.authorization_checker' => 'Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface', 'templating' => 'Symfony\Component\Templating\EngineInterface', 'twig' => 'Twig\Environment', - 'doctrine' => ManagerRegistry::class, + 'doctrine' => 'Doctrine\Persistence\ManagerRegistry', 'form.factory' => 'Symfony\Component\Form\FormFactoryInterface', 'security.csrf.token_manager' => 'Symfony\Component\Security\Core\Authorization\CsrfTokenManagerInterface', 'parameter_bag' => 'Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface', diff --git a/rules/Symfony60/Rector/MethodCall/GetHelperControllerToServiceRector.php b/rules/Symfony60/Rector/MethodCall/GetHelperControllerToServiceRector.php index bbc4325f2..2744429dc 100644 --- a/rules/Symfony60/Rector/MethodCall/GetHelperControllerToServiceRector.php +++ b/rules/Symfony60/Rector/MethodCall/GetHelperControllerToServiceRector.php @@ -4,7 +4,6 @@ namespace Rector\Symfony\Symfony60\Rector\MethodCall; -use Doctrine\Persistence\ManagerRegistry; use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\PropertyFetch; @@ -150,10 +149,10 @@ private function createMessageBusPropertyMetadata(): PropertyMetadata private function createManagerRegistryPropertyMetadata(): PropertyMetadata { - $propertyName = $this->propertyNaming->fqnToVariableName(ManagerRegistry::class); + $propertyName = $this->propertyNaming->fqnToVariableName('Doctrine\Persistence\ManagerRegistry'); // add dependency - $propertyObjectType = new ObjectType(ManagerRegistry::class); + $propertyObjectType = new ObjectType('Doctrine\Persistence\ManagerRegistry'); return new PropertyMetadata($propertyName, $propertyObjectType); } } diff --git a/rules/Symfony61/Rector/Class_/MagicClosureTwigExtensionToNativeMethodsRector.php b/rules/Symfony61/Rector/Class_/MagicClosureTwigExtensionToNativeMethodsRector.php index 569764677..1d5d8e5b9 100644 --- a/rules/Symfony61/Rector/Class_/MagicClosureTwigExtensionToNativeMethodsRector.php +++ b/rules/Symfony61/Rector/Class_/MagicClosureTwigExtensionToNativeMethodsRector.php @@ -20,9 +20,7 @@ use Rector\Rector\AbstractRector; use Rector\Symfony\Enum\TwigClass; use Rector\ValueObject\PhpVersion; -use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; -use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -31,7 +29,7 @@ * * @see PHP 8.1 way to handle functions/filters https://github.com/symfony/symfony/blob/e0ad2eead3513a558c09d8aa3ae9e867fb10b419/src/Symfony/Bridge/Twig/Extension/CodeExtension.php#L41-L52 */ -final class MagicClosureTwigExtensionToNativeMethodsRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface +final class MagicClosureTwigExtensionToNativeMethodsRector extends AbstractRector implements MinPhpVersionInterface { public function __construct( private readonly ArrayCallableMethodMatcher $arrayCallableMethodMatcher, @@ -39,11 +37,6 @@ public function __construct( ) { } - public function provideComposerPackageConstraint(): ComposerPackageConstraint - { - return new ComposerPackageConstraint('symfony/twig-bridge', '>=6.1'); - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony62/Rector/ClassMethod/ParamConverterAttributeToMapEntityAttributeRector.php b/rules/Symfony62/Rector/ClassMethod/ParamConverterAttributeToMapEntityAttributeRector.php index 26cb0d45a..c294985fb 100644 --- a/rules/Symfony62/Rector/ClassMethod/ParamConverterAttributeToMapEntityAttributeRector.php +++ b/rules/Symfony62/Rector/ClassMethod/ParamConverterAttributeToMapEntityAttributeRector.php @@ -20,9 +20,7 @@ use Rector\Symfony\Enum\SensioAttribute; use Rector\Symfony\Enum\SymfonyAnnotation; use Rector\ValueObject\PhpVersionFeature; -use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; -use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -31,18 +29,13 @@ * * @see \Rector\Symfony\Tests\Symfony62\Rector\ClassMethod\ParamConverterAttributeToMapEntityAttributeRector\ParamConverterAttributeToMapEntityAttributeRectorTest */ -final class ParamConverterAttributeToMapEntityAttributeRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface +final class ParamConverterAttributeToMapEntityAttributeRector extends AbstractRector implements MinPhpVersionInterface { public function provideMinPhpVersion(): int { return PhpVersionFeature::ATTRIBUTES; } - public function provideComposerPackageConstraint(): ComposerPackageConstraint - { - return new ComposerPackageConstraint('symfony/doctrine-bridge', '>=6.2'); - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php b/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php index 74ba56b3c..7fc46d93a 100644 --- a/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php +++ b/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php @@ -14,16 +14,14 @@ use Rector\Symfony\NodeManipulator\ClassManipulator; use Rector\Symfony\ValueObject\ServiceDefinition; use Rector\ValueObject\PhpVersionFeature; -use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; -use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @see \Rector\Symfony\Tests\Symfony62\Rector\Class_\MessageHandlerInterfaceToAttributeRector\MessageHandlerToAttributeRectorTest */ -final class MessageHandlerInterfaceToAttributeRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface +final class MessageHandlerInterfaceToAttributeRector extends AbstractRector implements MinPhpVersionInterface { public function __construct( private readonly MessengerHelper $messengerHelper, @@ -38,11 +36,6 @@ public function provideMinPhpVersion(): int return PhpVersionFeature::ATTRIBUTES; } - public function provideComposerPackageConstraint(): ComposerPackageConstraint - { - return new ComposerPackageConstraint('symfony/messenger', '>=6.2'); - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/rules/Symfony62/Rector/Class_/MessageSubscriberInterfaceToAttributeRector.php b/rules/Symfony62/Rector/Class_/MessageSubscriberInterfaceToAttributeRector.php index 37132858b..484807163 100644 --- a/rules/Symfony62/Rector/Class_/MessageSubscriberInterfaceToAttributeRector.php +++ b/rules/Symfony62/Rector/Class_/MessageSubscriberInterfaceToAttributeRector.php @@ -20,16 +20,14 @@ use Rector\Symfony\NodeManipulator\ClassManipulator; use Rector\ValueObject\MethodName; use Rector\ValueObject\PhpVersionFeature; -use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface; -use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @see \Rector\Symfony\Tests\Symfony62\Rector\Class_\MessageSubscriberInterfaceToAttributeRector\MessageSubscriberInterfaceToAttributeRectorTest */ -final class MessageSubscriberInterfaceToAttributeRector extends AbstractRector implements MinPhpVersionInterface, ComposerPackageConstraintInterface +final class MessageSubscriberInterfaceToAttributeRector extends AbstractRector implements MinPhpVersionInterface { private string $newInvokeMethodName; @@ -46,11 +44,6 @@ public function provideMinPhpVersion(): int return PhpVersionFeature::ATTRIBUTES; } - public function provideComposerPackageConstraint(): ComposerPackageConstraint - { - return new ComposerPackageConstraint('symfony/messenger', '>=6.2'); - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( diff --git a/src/Set/SetProvider/SymfonySetProvider.php b/src/Set/SetProvider/SymfonySetProvider.php index e47675b8b..2be218cea 100644 --- a/src/Set/SetProvider/SymfonySetProvider.php +++ b/src/Set/SetProvider/SymfonySetProvider.php @@ -30,10 +30,7 @@ final class SymfonySetProvider implements SetProviderInterface 'symfony/property-access' => '>=5.2', 'symfony/property-info' => '>=5.2', 'symfony/validator' => '>=5.2', - 'symfony/twig-bridge' => '>=6.1', - 'symfony/doctrine-bridge' => '>=6.2', 'symfony/http-kernel' => '>=6.2', - 'symfony/messenger' => '>=6.2', ]; /**