Skip to content

Commit

Permalink
Updated Rector to commit 684f23d165407e0461a48d2c1fd289834a492876
Browse files Browse the repository at this point in the history
rectorphp/rector-src@684f23d [DX] [Experimental] Add withPhpLevel() to raise PHP level one rule at a time (#6261)
  • Loading branch information
TomasVotruba committed Oct 12, 2024
1 parent 8defa24 commit 8388edb
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/Application/VersionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'd7bfc24bedc11374868f5a7ff3066eb847e80a8c';
public const PACKAGE_VERSION = '684f23d165407e0461a48d2c1fd289834a492876';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2024-10-12 17:38:13';
public const RELEASE_DATE = '2024-10-12 17:53:31';
/**
* @var int
*/
Expand Down
47 changes: 37 additions & 10 deletions src/Bridge/SetRectorsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,58 @@

use Rector\Config\RectorConfig;
use Rector\Contract\Rector\RectorInterface;
use ReflectionProperty;
use RectorPrefix202410\Webmozart\Assert\Assert;
/**
* @api
* @experimental since 1.1.2
* Utils class to ease building bridges by 3rd-party tools
*
* @see \Rector\Tests\Bridge\SetRectorsResolverTest
*/
final class SetRectorsResolver
{
/**
* @return array<class-string<RectorInterface>>
* @param string[] $configFilePaths
* @return array<int, class-string<RectorInterface>|array<class-string<RectorInterface>, mixed[]>>
*/
public function resolveFromFilePath(string $configFilePath) : array
public function resolveFromFilePathsIncludingConfiguration(array $configFilePaths) : array
{
Assert::allString($configFilePaths);
Assert::allFileExists($configFilePaths);
$combinedRectorRulesWithConfiguration = [];
foreach ($configFilePaths as $configFilePath) {
$rectorRulesWithConfiguration = $this->resolveFromFilePathIncludingConfiguration($configFilePath);
$combinedRectorRulesWithConfiguration = \array_merge($combinedRectorRulesWithConfiguration, $rectorRulesWithConfiguration);
}
return $combinedRectorRulesWithConfiguration;
}
/**
* @return array<int, class-string<RectorInterface>|array<class-string<RectorInterface>, mixed[]>>
*/
public function resolveFromFilePathIncludingConfiguration(string $configFilePath) : array
{
$rectorConfig = $this->loadRectorConfigFromFilePath($configFilePath);
$rectorClassesWithOptionalConfiguration = $rectorConfig->getRectorClasses();
foreach ($rectorConfig->getRuleConfigurations() as $rectorClass => $configuration) {
// remove from non-configurable, if added again with better config
if (\in_array($rectorClass, $rectorClassesWithOptionalConfiguration)) {
$rectorRulePosition = \array_search($rectorClass, $rectorClassesWithOptionalConfiguration, \true);
if (\is_int($rectorRulePosition)) {
unset($rectorClassesWithOptionalConfiguration[$rectorRulePosition]);
}
}
$rectorClassesWithOptionalConfiguration[] = [$rectorClass => $configuration];
}
// sort keys
return \array_values($rectorClassesWithOptionalConfiguration);
}
private function loadRectorConfigFromFilePath(string $configFilePath) : RectorConfig
{
Assert::fileExists($configFilePath);
$rectorConfig = new RectorConfig();
/** @var callable $configCallable */
$configCallable = (require $configFilePath);
$configCallable($rectorConfig);
// get tagged class-names
$tagsReflectionProperty = new ReflectionProperty($rectorConfig, 'tags');
$tagsReflectionProperty->setAccessible(\true);
$tags = $tagsReflectionProperty->getValue($rectorConfig);
$rectorClasses = $tags[RectorInterface::class] ?? [];
\sort($rectorClasses);
return \array_unique($rectorClasses);
return $rectorConfig;
}
}
35 changes: 35 additions & 0 deletions src/Configuration/RectorConfigBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use RectorPrefix202410\Nette\Utils\FileSystem;
use Rector\Bridge\SetProviderCollector;
use Rector\Bridge\SetRectorsResolver;
use Rector\Caching\Contract\ValueObject\Storage\CacheStorageInterface;
use Rector\Config\Level\CodeQualityLevel;
use Rector\Config\Level\DeadCodeLevel;
Expand Down Expand Up @@ -186,6 +187,10 @@ final class RectorConfigBuilder
* @var bool|null
*/
private $isWithPhpSetsUsed;
/**
* @var bool|null
*/
private $isWithPhpLevelUsed;
public function __invoke(RectorConfig $rectorConfig) : void
{
// @experimental 2024-06
Expand All @@ -197,6 +202,9 @@ public function __invoke(RectorConfig $rectorConfig) : void
// merge sets together
$this->sets = \array_merge($this->sets, $this->groupLoadedSets);
$uniqueSets = \array_unique($this->sets);
if ($this->isWithPhpLevelUsed && $this->isWithPhpSetsUsed) {
throw new InvalidConfigurationException(\sprintf('Your config uses "withPhp*()" and "withPhpLevel()" methods at the same time.%sPick one of them to avoid rule conflicts.', \PHP_EOL));
}
if (\in_array(SetList::TYPE_DECLARATION, $uniqueSets, \true) && $this->isTypeCoverageLevelUsed === \true) {
throw new InvalidConfigurationException(\sprintf('Your config already enables type declarations set.%sRemove "->withTypeCoverageLevel()" as it only duplicates it, or remove type declaration set.', \PHP_EOL));
}
Expand Down Expand Up @@ -763,6 +771,33 @@ public function withTypeCoverageLevel(int $level) : self
$this->rules = \array_merge($this->rules, $levelRules);
return $this;
}
/**
* @experimental Since 1.2.5 Raise your PHP level from, one level at a time
*/
public function withPhpLevel(int $level) : self
{
Assert::natural($level);
$this->isWithPhpLevelUsed = \true;
$phpVersion = ComposerJsonPhpVersionResolver::resolveFromCwdOrFail();
$setRectorsResolver = new SetRectorsResolver();
$setFilePaths = \Rector\Configuration\PhpLevelSetResolver::resolveFromPhpVersion($phpVersion);
$rectorRulesWithConfiguration = $setRectorsResolver->resolveFromFilePathsIncludingConfiguration($setFilePaths);
foreach ($rectorRulesWithConfiguration as $position => $rectorRuleWithConfiguration) {
// add rules untill level is reached
if ($position > $level) {
continue;
}
if (\is_string($rectorRuleWithConfiguration)) {
$this->rules[] = $rectorRuleWithConfiguration;
} elseif (\is_array($rectorRuleWithConfiguration)) {
foreach ($rectorRuleWithConfiguration as $rectorRule => $rectorRuleConfiguration) {
/** @var class-string<ConfigurableRectorInterface> $rectorRule */
$this->withConfiguredRule($rectorRule, $rectorRuleConfiguration);
}
}
}
return $this;
}
/**
* @experimental Raise your code quality from the safest rules
* to more affecting ones, one level at a time
Expand Down

0 comments on commit 8388edb

Please sign in to comment.