From 65e9c8eb02b2dbf03d4fc7149f093c766e5885af Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 3 Aug 2026 15:14:54 +0200 Subject: [PATCH 1/2] [NetteUtils] Bind nette/utils rules to installed package version Same approach as rectorphp/rector-symfony#979: rules declare their own composer package constraint, the set is triggered by any installed nette/utils version. --- .../{nette-utils4.php => composer-based.php} | 2 ++ .../UtilsJsonStaticCallNamedArgRector.php | 13 ++++++++++++- src/Set/SetProvider/CoreSetProvider.php | 6 ++++-- 3 files changed, 18 insertions(+), 3 deletions(-) rename config/set/nette-utils/{nette-utils4.php => composer-based.php} (68%) diff --git a/config/set/nette-utils/nette-utils4.php b/config/set/nette-utils/composer-based.php similarity index 68% rename from config/set/nette-utils/nette-utils4.php rename to config/set/nette-utils/composer-based.php index d07fdd94e4b..28d9436e92a 100644 --- a/config/set/nette-utils/nette-utils4.php +++ b/config/set/nette-utils/composer-based.php @@ -5,6 +5,8 @@ use Rector\Config\RectorConfig; use Rector\NetteUtils\Rector\StaticCall\UtilsJsonStaticCallNamedArgRector; +// applies to any installed nette/utils version, the rules inside are bound +// to the exact version they are available from return static function (RectorConfig $rectorConfig): void { $rectorConfig->rules([UtilsJsonStaticCallNamedArgRector::class]); }; diff --git a/rules/NetteUtils/Rector/StaticCall/UtilsJsonStaticCallNamedArgRector.php b/rules/NetteUtils/Rector/StaticCall/UtilsJsonStaticCallNamedArgRector.php index ef5aade25d6..0f932ec050b 100644 --- a/rules/NetteUtils/Rector/StaticCall/UtilsJsonStaticCallNamedArgRector.php +++ b/rules/NetteUtils/Rector/StaticCall/UtilsJsonStaticCallNamedArgRector.php @@ -10,14 +10,25 @@ use PhpParser\Node\Identifier; use Rector\Rector\AbstractRector; use Rector\TypeDeclarationDocblocks\Enum\NetteClassName; +use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; +use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @see \Rector\Tests\NetteUtils\Rector\StaticCall\UtilsJsonStaticCallNamedArgRector\UtilsJsonStaticCallNamedArgRectorTest */ -final class UtilsJsonStaticCallNamedArgRector extends AbstractRector +final class UtilsJsonStaticCallNamedArgRector extends AbstractRector implements ComposerPackageConstraintInterface { + /** + * The bool $pretty and bool $forceArrays params were added in nette/utils 4.0, + * before that both methods took int $flags + */ + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('nette/utils', '>=4.0'); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Change `' . Json::class . '::encode()` and `decode()` to named args', [ diff --git a/src/Set/SetProvider/CoreSetProvider.php b/src/Set/SetProvider/CoreSetProvider.php index 6673cfe9a6c..3708188743e 100644 --- a/src/Set/SetProvider/CoreSetProvider.php +++ b/src/Set/SetProvider/CoreSetProvider.php @@ -29,11 +29,13 @@ public function provide(): array new Set(SetGroup::CORE, 'Privatization', __DIR__ . '/../../../config/set/privatization.php'), new Set(SetGroup::CORE, 'Type Declarations', __DIR__ . '/../../../config/set/type-declaration.php'), + // applies to any installed nette/utils version, the rules inside are bound + // to the exact version they are available from new ComposerTriggeredSet( SetGroup::NETTE_UTILS, 'nette/utils', - '4.0', - __DIR__ . '/../../../config/set/nette-utils/nette-utils4.php', + '>=2.0', + __DIR__ . '/../../../config/set/nette-utils/composer-based.php', ), ]; } From 819323f99da23d32ccef2b4c2b1dab5640a710ee Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 3 Aug 2026 15:18:55 +0200 Subject: [PATCH 2/2] [NetteUtils] Register composer-based set directly in withComposerBased(), drop nette-utils set group --- src/Configuration/RectorConfigBuilder.php | 6 +++++- src/Set/Enum/SetGroup.php | 5 ----- src/Set/SetProvider/CoreSetProvider.php | 10 ---------- src/Set/ValueObject/SetList.php | 6 ++++++ 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/Configuration/RectorConfigBuilder.php b/src/Configuration/RectorConfigBuilder.php index 4df8adcf018..6619f46b1d0 100644 --- a/src/Configuration/RectorConfigBuilder.php +++ b/src/Configuration/RectorConfigBuilder.php @@ -739,7 +739,6 @@ public function withComposerBased( $setMap = [ SetGroup::TWIG => $twig, SetGroup::DOCTRINE => $doctrine, - SetGroup::NETTE_UTILS => $netteUtils, SetGroup::LARAVEL => $laravel, SetGroup::DRUPAL => $drupal, ]; @@ -760,6 +759,11 @@ public function withComposerBased( $this->sets[] = SymfonySetList::COMPOSER_BASED; } + if ($netteUtils) { + // single set, as every rule inside is bound to the installed nette/utils version on its own + $this->sets[] = SetList::NETTE_UTILS_COMPOSER_BASED; + } + return $this; } diff --git a/src/Set/Enum/SetGroup.php b/src/Set/Enum/SetGroup.php index 59b8b133d43..06d83d4a18f 100644 --- a/src/Set/Enum/SetGroup.php +++ b/src/Set/Enum/SetGroup.php @@ -33,11 +33,6 @@ final class SetGroup */ public const string SYMFONY = 'symfony'; - /** - * Version-based set provider - */ - public const string NETTE_UTILS = 'nette-utils'; - /** * Version-based set provider */ diff --git a/src/Set/SetProvider/CoreSetProvider.php b/src/Set/SetProvider/CoreSetProvider.php index 3708188743e..1ce42614582 100644 --- a/src/Set/SetProvider/CoreSetProvider.php +++ b/src/Set/SetProvider/CoreSetProvider.php @@ -7,7 +7,6 @@ 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 CoreSetProvider implements SetProviderInterface @@ -28,15 +27,6 @@ public function provide(): array new Set(SetGroup::CORE, 'Naming', __DIR__ . '/../../../config/set/naming.php'), new Set(SetGroup::CORE, 'Privatization', __DIR__ . '/../../../config/set/privatization.php'), new Set(SetGroup::CORE, 'Type Declarations', __DIR__ . '/../../../config/set/type-declaration.php'), - - // applies to any installed nette/utils version, the rules inside are bound - // to the exact version they are available from - new ComposerTriggeredSet( - SetGroup::NETTE_UTILS, - 'nette/utils', - '>=2.0', - __DIR__ . '/../../../config/set/nette-utils/composer-based.php', - ), ]; } } diff --git a/src/Set/ValueObject/SetList.php b/src/Set/ValueObject/SetList.php index c6fa325f779..ef99d8ede9f 100644 --- a/src/Set/ValueObject/SetList.php +++ b/src/Set/ValueObject/SetList.php @@ -30,6 +30,12 @@ final class SetList public const string NAMED_ARGS = __DIR__ . '/../../../config/set/named-args.php'; + /** + * Applies to any installed nette/utils version, the rules inside are bound + * to the exact version they are available from + */ + public const string NETTE_UTILS_COMPOSER_BASED = __DIR__ . '/../../../config/set/nette-utils/composer-based.php'; + /** * Opinionated rules that match rector coding standard */