Skip to content

[composer-based] Bond remaining 48 Symfony rules to their composer package version - #994

Merged
TomasVotruba merged 2 commits into
mainfrom
composer-based-bond-remaining-symfony-rules
Aug 3, 2026
Merged

[composer-based] Bond remaining 48 Symfony rules to their composer package version#994
TomasVotruba merged 2 commits into
mainfrom
composer-based-bond-remaining-symfony-rules

Conversation

@TomasVotruba

@TomasVotruba TomasVotruba commented Aug 3, 2026

Copy link
Copy Markdown
Member

Follow-up to #991. Every remaining Symfony rule that lived only in a per-version set now declares the package and version its target API was added in, and is registered in the composer-based set too.

The per-version sets are not touched — every rule stays exactly where it was registered.

What a bonded rule looks like

-final class GetCurrencyBundleMethodCallsToIntlRector extends AbstractRector
+final class GetCurrencyBundleMethodCallsToIntlRector extends AbstractRector implements ComposerPackageConstraintInterface
 {
+    public function provideComposerPackageConstraint(): ComposerPackageConstraint
+    {
+        return new ComposerPackageConstraint('symfony/intl', '>=4.3');
+    }

Effect for the user: on a project without symfony/intl, or with it below 4.3, the rule is skipped instead of firing on unrelated code.

The set

config/sets/symfony/composer-based.php goes from 23 to 71 rules. The list is rebuilt version-sorted and grouped per package, non-Symfony packages last:

+        // symfony/intl 4.3
+        GetCurrencyBundleMethodCallsToIntlRector::class,
+
+        // symfony/twig-bundle 4.3
+        TwigBundleFilesystemLoaderToTwigRector::class,

The blanket // symfony/* 5.2 and // attributes added in Symfony 6.2 comments are replaced by the exact package + version per group, read back from each rule's own constraint.

Test composer.json stubs

48 rule tests get a standalone config/composer.json and a provideComposerJsonFilePath() override, following the RedirectToRouteRector precedent from #991:

{
    "require": {
        "symfony/intl": "^4.3"
    }
}

Needed because the bonded package is either not installed here at all (symfony/form, symfony/intl, symfony/messenger, symfony/framework-bundle, symfony/doctrine-bridge, symfony/twig-bundle, symfony/twig-bridge, symfony/uid, twig/twig), or installed below the bonded version — the 8.1 constraints on symfony/uid, symfony/security-http, symfony/filesystem and symfony/validator cannot coexist with the 6.4/7.4 dev dependencies. No require-dev versions are changed.

Judgement calls worth a look

  • The three Sensio rules in symfony34-sensio-framework-extra-bundle are bonded to symfony/routing >=3.4, not to sensio/framework-extra-bundle — Sensio's own versions do not track Symfony's, and the target API is Symfony's Route annotation.
  • GetFiltersToAsTwigFilterAttributeRector and GetFunctionsToAsTwigFunctionAttributeRector are bonded to twig/twig >=3.21, where Twig\Attribute\AsTwigFilter/AsTwigFunction landed.
  • MagicClosureTwigExtensionToNativeMethodsRector is bonded to symfony/twig-bridge >=6.1. It already gates on PHP 8.1 through MinPhpVersionInterface for the first-class callable syntax it produces; 6.1 is where symfony/twig-bridge adopted that style in CodeExtension, and Symfony 6.1 requires PHP 8.1, so both gates open together.

Still unregistered anywhere (pre-existing, untouched)

InvokableCommandInputAttributeRector, SimplifyFormRenderingRector, WebTestCaseAssertIsSuccessfulRector, WebTestCaseAssertResponseCodeRector are in no set at all. Separate PR.

…ckage version

Every rule that was only reachable through a per-version set now declares
the package and version its target API was added in, and is registered in
the composer-based set as well. The per-version sets are left untouched.

Rules bonded to a package that is not installed here, or installed below
the bonded version, get a standalone composer.json in their test config,
following the RedirectToRouteRector precedent.
…to symfony/twig-bridge 6.1

The rule already gates on PHP 8.1 for the first-class callable syntax it
produces. The composer constraint pins the matching Symfony side: the
first-class callable style in Twig extensions landed in symfony/twig-bridge
6.1, which itself requires PHP 8.1, so both gates open together.
@TomasVotruba TomasVotruba changed the title [composer-based] Bond remaining 47 Symfony rules to their composer package version [composer-based] Bond remaining 48 Symfony rules to their composer package version Aug 3, 2026
@TomasVotruba
TomasVotruba merged commit e6de0b6 into main Aug 3, 2026
7 checks passed
@TomasVotruba
TomasVotruba deleted the composer-based-bond-remaining-symfony-rules branch August 3, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant