From 0836e00b0ec96b45c69e2107a91b62e4f6533253 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 29 Aug 2026 21:15:03 +0200 Subject: [PATCH 1/3] [dx] load composer-based sets from laravel and drupal --- composer.json | 3 +- src/Configuration/RectorConfigBuilder.php | 36 +++++------------------ src/Set/Enum/SetGroup.php | 2 ++ 3 files changed, 11 insertions(+), 30 deletions(-) diff --git a/composer.json b/composer.json index 6ead49b6f70..d1dc4f51bd3 100644 --- a/composer.json +++ b/composer.json @@ -41,8 +41,8 @@ "webmozart/assert": "^2.4" }, "require-dev": { + "driftingly/rector-laravel": "^2.6", "nette/robot-loader": "^4.1", - "symfony/process": "^8.1", "php-parallel-lint/php-parallel-lint": "^1.4", "phpstan/extension-installer": "^1.4", "phpstan/phpstan-deprecation-rules": "^2.0", @@ -52,6 +52,7 @@ "rector/jack": "^1.1", "rector/swiss-knife": "^2.4.1", "shipmonk/composer-dependency-analyser": "^1.8", + "symfony/process": "^8.1", "symplify/easy-coding-standard": "^13.2.13", "symplify/phpstan-rules": "^14.13", "tomasvotruba/class-leak": "^2.1", diff --git a/src/Configuration/RectorConfigBuilder.php b/src/Configuration/RectorConfigBuilder.php index 9dfb8edaa59..748a768754d 100644 --- a/src/Configuration/RectorConfigBuilder.php +++ b/src/Configuration/RectorConfigBuilder.php @@ -24,7 +24,6 @@ use Rector\Exception\Configuration\InvalidConfigurationException; use Rector\Php\PhpVersionResolver\ComposerJsonPhpVersionResolver; use Rector\PHPUnit\Set\PHPUnitSetList; -use Rector\Set\Enum\SetGroup; use Rector\Set\ValueObject\DowngradeLevelSetList; use Rector\Set\ValueObject\SetList; use Rector\Symfony\Set\SymfonyInternalSetList; @@ -32,6 +31,7 @@ use Rector\Symfony\Set\TwigSetList; use Rector\ValueObject\Configuration\LevelOverflow; use Rector\ValueObject\PhpVersion; +use RectorLaravel\Set\LaravelSetList; use Symfony\Component\Finder\Finder; use Webmozart\Assert\Assert; @@ -56,17 +56,6 @@ final class RectorConfigBuilder 'withCodingStyleLevel' => [SetList::CODING_STYLE, 'coding style'], ]; - /** - * The composer-based set of the extensions that rector-src does not require, so their set list class cannot be - * imported here. Resolved at run-time; an extension that ships no such set falls back to its set group. - * - * @var array - */ - private const array EXTENSION_COMPOSER_BASED_SET_LISTS = [ - SetGroup::LARAVEL => 'RectorLaravel\\Set\\LaravelSetList::COMPOSER_BASED', - SetGroup::DRUPAL => 'DrupalRector\\Set\\DrupalSetList::COMPOSER_BASED', - ]; - /** * @var string[] */ @@ -693,24 +682,13 @@ public function withComposerBased( bool $laravel = false, bool $drupal = false, ): self { - $setMap = [ - SetGroup::LARAVEL => $laravel, - SetGroup::DRUPAL => $drupal, - ]; - - foreach ($setMap as $setGroup => $isEnabled) { - if (! $isEnabled) { - continue; - } - - $setListConstant = self::EXTENSION_COMPOSER_BASED_SET_LISTS[$setGroup]; - if (defined($setListConstant)) { - $setFilePath = constant($setListConstant); - Assert::string($setFilePath); + if ($laravel) { + $this->sets[] = LaravelSetList::COMPOSER_BASED; + } - // single set, as every rule inside is bound to the installed package version on its own - $this->sets[] = $setFilePath; - } + if ($drupal && class_exists('DrupalRector\Set\DrupalSetList')) { + // waits on https://github.com/palantirnet/drupal-rector/pull/419/files#diff-c6bd4ee854830efc1363a7d99c1b6a2e7e64f2499a51e503174ab777de7e64e5 + $this->sets[] = DrupalSetList::COMPOSER_BASED; } if ($phpunit) { diff --git a/src/Set/Enum/SetGroup.php b/src/Set/Enum/SetGroup.php index 7525b470c8f..cf455d295b8 100644 --- a/src/Set/Enum/SetGroup.php +++ b/src/Set/Enum/SetGroup.php @@ -14,11 +14,13 @@ final class SetGroup public const string PHP = 'php'; /** + * @deprecated Use composer-based.php set instead * Version-based set provider */ public const string LARAVEL = 'laravel'; /** + * @deprecated Use composer-based.php set instead * Version-based set provider */ public const string DRUPAL = 'drupal'; From 97f53e55facd5498eff5ba99acbd85a815c63b4b Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 29 Aug 2026 21:59:51 +0200 Subject: [PATCH 2/3] remove unused test --- phpstan.neon | 4 +- .../ExtensionComposerBasedSetTest.php | 72 ------------------- 2 files changed, 2 insertions(+), 74 deletions(-) delete mode 100644 tests/Configuration/ExtensionComposerBasedSetTest.php diff --git a/phpstan.neon b/phpstan.neon index a782535dc7b..4902f6211a5 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -73,8 +73,8 @@ parameters: # EARLY_RETURN set is deprecated (empty, merged into code-quality), still mapped internally until removed - identifier: classConstant.deprecated - message: '#EARLY_RETURN of class Rector\\Set\\ValueObject\\SetList#' - path: src/Configuration/RectorConfigBuilder.php + paths: + - src/Configuration/RectorConfigBuilder.php # the deprecated github/gitlab output formatters are still tested until removed in next minor version - diff --git a/tests/Configuration/ExtensionComposerBasedSetTest.php b/tests/Configuration/ExtensionComposerBasedSetTest.php deleted file mode 100644 index b7434a6cb52..00000000000 --- a/tests/Configuration/ExtensionComposerBasedSetTest.php +++ /dev/null @@ -1,72 +0,0 @@ -provideExtensionComposerBasedSetLists(); - - $this->assertArrayHasKey(SetGroup::LARAVEL, $extensionSetLists); - $this->assertArrayHasKey(SetGroup::DRUPAL, $extensionSetLists); - - foreach ($extensionSetLists as $extensionSetList) { - $this->assertMatchesRegularExpression('#^\w+(\\\\\w+)+::\w+$#', $extensionSetList); - } - } - - /** - * The extension packages are not required by rector-src, so their constant is undefined here and - * nothing is loaded for the toggle. - */ - public function testLoadsNothingWhenTheExtensionIsNotInstalled(): void - { - foreach ($this->provideExtensionComposerBasedSetLists() as $setListConstant) { - $this->assertFalse(defined($setListConstant), $setListConstant); - } - - $rectorConfigBuilder = new RectorConfigBuilder() - ->withComposerBased(laravel: true, drupal: true); - - $this->assertSame([], $this->readPrivateArray($rectorConfigBuilder, 'sets')); - } - - /** - * @return array - */ - private function provideExtensionComposerBasedSetLists(): array - { - $extensionSetLists = new ReflectionClass(RectorConfigBuilder::class) - ->getConstant('EXTENSION_COMPOSER_BASED_SET_LISTS'); - - $this->assertIsArray($extensionSetLists); - - return $extensionSetLists; - } - - /** - * @return mixed[] - */ - private function readPrivateArray(RectorConfigBuilder $rectorConfigBuilder, string $propertyName): array - { - $value = new ReflectionClass($rectorConfigBuilder) - ->getProperty($propertyName) - ->getValue($rectorConfigBuilder); - - $this->assertIsArray($value); - - return $value; - } -} From e679ca130312601b73d53f7a99df6304ae2aa281 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 29 Aug 2026 22:06:50 +0200 Subject: [PATCH 3/3] cleanup --- composer.json | 1 - phpstan.neon | 5 +++++ src/Configuration/RectorConfigBuilder.php | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index d1dc4f51bd3..a4ac4f76ad7 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,6 @@ "webmozart/assert": "^2.4" }, "require-dev": { - "driftingly/rector-laravel": "^2.6", "nette/robot-loader": "^4.1", "php-parallel-lint/php-parallel-lint": "^1.4", "phpstan/extension-installer": "^1.4", diff --git a/phpstan.neon b/phpstan.neon index 4902f6211a5..3a0fd261b44 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -310,6 +310,7 @@ parameters: paths: - bin/rector.php - src/Bootstrap/ExtensionConfigResolver.php + - src/Configuration/RectorConfigBuilder.php - src/Validation/RectorConfigValidator.php - src/Testing/PHPUnit/AbstractLazyTestCase.php - src/Reporting/DeprecatedRulesReporter.php @@ -341,6 +342,10 @@ parameters: message: '#@\\ini_set\(.*\)" is forbidden to use#' path: bin/rector.php + - + message: '#PHPDoc tag @var with type array is not subtype of native type array#' + path: src/Bootstrap/ExtensionConfigResolver.php + - identifier: symplify.forbiddenStaticClassConstFetch message: '#Avoid static access of constants, as they can change value\. Use interface and contract method instead#' diff --git a/src/Configuration/RectorConfigBuilder.php b/src/Configuration/RectorConfigBuilder.php index 748a768754d..e11f2105a0f 100644 --- a/src/Configuration/RectorConfigBuilder.php +++ b/src/Configuration/RectorConfigBuilder.php @@ -682,13 +682,13 @@ public function withComposerBased( bool $laravel = false, bool $drupal = false, ): self { - if ($laravel) { + if ($laravel && class_exists('RectorLaravel\Set\LaravelSetList') && constant('RectorLaravel\Set\LaravelSetList::COMPOSER_BASED')) { $this->sets[] = LaravelSetList::COMPOSER_BASED; } - if ($drupal && class_exists('DrupalRector\Set\DrupalSetList')) { + if ($drupal && class_exists('DrupalRector\Set\DrupalSetList') && constant('DrupalRector\Set\DrupalSetList::COMPOSER_BASED')) { // waits on https://github.com/palantirnet/drupal-rector/pull/419/files#diff-c6bd4ee854830efc1363a7d99c1b6a2e7e64f2499a51e503174ab777de7e64e5 - $this->sets[] = DrupalSetList::COMPOSER_BASED; + $this->sets[] = \DrupalRector\Set\DrupalSetList::COMPOSER_BASED; } if ($phpunit) {