Skip to content

[composer-based] Bond version-specific rules and configuration to composer package constraints - #495

Merged
TomasVotruba merged 2 commits into
mainfrom
composer-based-version-bound-rules
Aug 1, 2026
Merged

[composer-based] Bond version-specific rules and configuration to composer package constraints#495
TomasVotruba merged 2 commits into
mainfrom
composer-based-version-bound-rules

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Same shape as rector-phpunit #754 and rector-symfony #979 / #980, applied to Doctrine.

What

A single new set, config/sets/composer-based.php, holding everything bound to the exact Doctrine package version its target API was added in.

13 rules declare their own constraint:

final class ReplaceFetchAllMethodCallRector extends AbstractRector implements ComposerPackageConstraintInterface
{
    public function provideComposerPackageConstraint(): ComposerPackageConstraint
    {
        return new ComposerPackageConstraint('doctrine/dbal', '>=2.11');
    }
}

And the 20 configurations of the version sets are registered version bound:

// doctrine/dbal 4.0
$rectorConfig->ruleWithConfigurationComposerVersionBound(RenameMethodRector::class, [
    new MethodCallRename('Doctrine\DBAL\Connection', 'getSchemaManager', 'createSchemaManager'),
], 'doctrine/dbal', '>=4.0');

Effect

A project on doctrine/dbal 4.4 gets both renames in one run, without picking the doctrine-dbal-40 set and no matter which DBAL version the upgrade started from:

 public function run(Connection $connection, Index $index)
 {
-    $schemaManager = $connection->getSchemaManager();
-    $isFulfilled = $index->isFullfilledBy([]);
+    $schemaManager = $connection->createSchemaManager();
+    $isFulfilled = $index->isFulfilledBy([]);
 }

And the same rules are skipped on a project still on DBAL 3, where those methods do not exist yet.

Notes

  • Existing sets stay untouched, composer.json too - only the rector/rector-src lock entry moved, as the older one never assigned InstalledPackageResolver::$projectDirectory and every constrained rule died on "installed package json not found".
  • Trigger packages: 7, one per package used inside the set, each from the lowest version its rules require.
  • doctrine-orm-28.php, doctrine-orm-219.php and doctrine-bundle-210.php have no composer trigger of their own, their version comes from the file name.
  • Rules of doctrine/data-fixtures, doctrine/common and doctrine/mongodb-odm are not bonded: those packages are not dev dependencies, so the constraint would filter the rule out and its test would silently stop transforming. Their configuration is included, as it needs no test package. Follow-up once the dev deps allow it.
  • Unrelated: the provider triggers doctrine-collection-22.php on doctrine/collection, but the package is doctrine/collections, so that set never matches. The rule inside is bonded to doctrine/collections here.
  • The rector CI job also reports a docblock change in CaseStringHelper - that one is already on main, untouched by this PR.

…poser package constraints

Add config/sets/composer-based.php, a single set holding the rules and
configuration bound to the exact Doctrine package version their target API was
added in, mirroring the rector-phpunit and rector-symfony composer-based sets.

Rules declare their constraint via ComposerPackageConstraintInterface, the
configuration of the version sets is registered through
ruleWithConfigurationComposerVersionBound(). Both apply to any project with
that package version installed, no matter which version the upgrade started
from.

Doctrine has no single package to trigger on, so every package used inside the
set registers it as a ComposerTriggeredSet.

Existing sets and composer.json stay untouched.
@TomasVotruba
TomasVotruba force-pushed the composer-based-version-bound-rules branch from f5c95a6 to 51be8f4 Compare August 1, 2026 19:22
@TomasVotruba
TomasVotruba merged commit 3c3f2c1 into main Aug 1, 2026
7 checks passed
@TomasVotruba
TomasVotruba deleted the composer-based-version-bound-rules branch August 1, 2026 20:16
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.

2 participants