Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* `FileWithoutNamespace` is deprecated, and replaced by `FileNode` that represents both namespaced and non-namespaced files and allow changes inside
* `beforeTraverse()` is now marked as `@final`, use `getNodeTypes()` with `FileNode::class` instead
* The `junit` output format was removed, as Rector is not a testing tool. Use `--output-format=gitlab` or `--output-format=github` instead, based on your CI

**Before**

Expand Down
136 changes: 0 additions & 136 deletions src/ChangesReporting/Output/JUnitOutputFormatter.php

This file was deleted.

57 changes: 41 additions & 16 deletions src/Config/RectorConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ final class RectorConfig extends Container
*/
private array $ruleConfigurations = [];

/**
* @var array<class-string<RectorInterface>, true>
*/
private array $registeredRectorClasses = [];

/**
* @var array<string, true>
*/
private array $registeredComposerBoundRuleConfigurations = [];

/**
* @var string[]
*/
Expand Down Expand Up @@ -195,9 +205,6 @@ public function ruleWithConfiguration(string $rectorClass, array $configuration)
$ruleConfiguration = $this->ruleConfigurations[$rectorClass];
$configurableRector->configure($ruleConfiguration);
});

// for cache invalidation in case of sets change
SimpleParameterProvider::addParameter(Option::REGISTERED_RECTOR_RULES, $rectorClass);
}

/**
Expand All @@ -217,16 +224,25 @@ public function ruleWithConfigurationComposerVersionBound(
$packageVersion = $this->resolveInstalledPackageVersion($packageName);
$isActive = $packageVersion !== null && Semver::satisfies($packageVersion, $versionConstraint);

// reported by the "composer-based" command, the inactive ones as well
SimpleParameterProvider::addParameter(Option::COMPOSER_BOUND_RULE_CONFIGURATIONS, [
new ComposerBoundRuleConfiguration(
$rectorClass,
$packageName,
$versionConstraint,
$configuration,
$isActive
),
]);
// the same rule configuration can be registered by multiple sets, report it only once
$configurationKey = $rectorClass . '|' . $packageName . '|' . $versionConstraint . '|' . serialize(
$configuration
);

if (! isset($this->registeredComposerBoundRuleConfigurations[$configurationKey])) {
$this->registeredComposerBoundRuleConfigurations[$configurationKey] = true;

// reported by the "composer-based" command, the inactive ones as well
SimpleParameterProvider::addParameter(Option::COMPOSER_BOUND_RULE_CONFIGURATIONS, [
new ComposerBoundRuleConfiguration(
$rectorClass,
$packageName,
$versionConstraint,
$configuration,
$isActive
),
]);
}

if (! $isActive) {
return;
Expand All @@ -244,10 +260,17 @@ public function rule(string $rectorClass): void
Assert::isAOf($rectorClass, RectorInterface::class);

$this->singleton($rectorClass);
$this->tag($rectorClass, RectorInterface::class);

// for cache invalidation in case of change
SimpleParameterProvider::addParameter(Option::REGISTERED_RECTOR_RULES, $rectorClass);
// the same rule can be registered by multiple sets, tag it only once,
// otherwise it is run twice on every node and listed twice in the reports
if (! isset($this->registeredRectorClasses[$rectorClass])) {
$this->registeredRectorClasses[$rectorClass] = true;

$this->tag($rectorClass, RectorInterface::class);

// for cache invalidation in case of change
SimpleParameterProvider::addParameter(Option::REGISTERED_RECTOR_RULES, $rectorClass);
}

if (is_a($rectorClass, RelatedConfigInterface::class, true)) {
$configFile = $rectorClass::getConfigFile();
Expand Down Expand Up @@ -442,6 +465,8 @@ public function indent(string $character, int $count): void
public function resetRuleConfigurations(): void
{
$this->ruleConfigurations = [];
$this->registeredRectorClasses = [];
$this->registeredComposerBoundRuleConfigurations = [];
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/Configuration/ConfigurationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ public function createFromInput(InputInterface $input): Configuration

$showRulesSummary = (bool) $input->getOption(Option::RULES_SUMMARY);

$isComposerBased = (bool) $input->getOption(Option::COMPOSER_BASED);

// "--composer-based" narrows the run the same way "--only" does
if ($isComposerBased) {
SimpleParameterProvider::setParameter(Option::IS_RUN_NARROWED, true);
}

return new Configuration(
$isDryRun,
$showProgressBar,
Expand All @@ -113,6 +120,7 @@ public function createFromInput(InputInterface $input): Configuration
$onlySuffix,
$levelOverflows,
$showRulesSummary,
$isComposerBased,
);
}

Expand Down
58 changes: 58 additions & 0 deletions src/Configuration/ConfigurationRuleFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

namespace Rector\Configuration;

use Rector\Configuration\Parameter\SimpleParameterProvider;
use Rector\Contract\Rector\RectorInterface;
use Rector\ValueObject\Configuration;
use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface;
use Rector\VersionBonding\ValueObject\ComposerBoundRuleConfiguration;

/**
* Modify available rector rules based on the configuration options
Expand Down Expand Up @@ -34,6 +37,10 @@ public function filter(array $rectors): array
return $this->filterOnlyRule($rectors, $onlyRule);
}

if ($this->configuration->isComposerBased()) {
return $this->filterComposerBased($rectors);
}

return $rectors;
}

Expand All @@ -52,4 +59,55 @@ public function filterOnlyRule(array $rectors, string $onlyRule): array

return $activeRectors;
}

/**
* Keeps rules that declare a composer package constraint themselves, and rules whose configuration
* was registered with a composer package constraint.
*
* @param list<RectorInterface> $rectors
* @return list<RectorInterface>
*/
private function filterComposerBased(array $rectors): array
{
$composerBoundRectorClasses = $this->resolveComposerBoundRectorClasses();

$activeRectors = [];
foreach ($rectors as $rector) {
if ($rector instanceof ComposerPackageConstraintInterface) {
$activeRectors[] = $rector;
continue;
}

if (in_array($rector::class, $composerBoundRectorClasses, true)) {
$activeRectors[] = $rector;
}
}

return $activeRectors;
}

/**
* @return string[]
*/
private function resolveComposerBoundRectorClasses(): array
{
$composerBoundRuleConfigurations = SimpleParameterProvider::provideArrayParameter(
Option::COMPOSER_BOUND_RULE_CONFIGURATIONS
);

$rectorClasses = [];
foreach ($composerBoundRuleConfigurations as $composerBoundRuleConfiguration) {
if (! $composerBoundRuleConfiguration instanceof ComposerBoundRuleConfiguration) {
continue;
}

if (! $composerBoundRuleConfiguration->isActive()) {
continue;
}

$rectorClasses[] = $composerBoundRuleConfiguration->getRectorClass();
}

return $rectorClasses;
}
}
5 changes: 5 additions & 0 deletions src/Configuration/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ final class Option
*/
public const string COMPOSER_BOUND_RULE_CONFIGURATIONS = 'composer_bound_rule_configurations';

/**
* Run only rules bound to an installed composer package version
*/
public const string COMPOSER_BASED = 'composer-based';

/**
* @internal To filter files by specific suffix
*/
Expand Down
7 changes: 7 additions & 0 deletions src/Console/ProcessConfigureDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ public static function decorate(Command $command): void
// filter by rule and path
$command->addOption(Option::ONLY, null, InputOption::VALUE_REQUIRED, 'Fully qualified rule class name');

$command->addOption(
Option::COMPOSER_BASED,
null,
InputOption::VALUE_NONE,
'Run only rules bound to an installed composer package version'
);

$command->addOption(
Option::ONLY_SUFFIX,
null,
Expand Down
2 changes: 0 additions & 2 deletions src/DependencyInjection/LazyContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
use Rector\ChangesReporting\Output\GitHubOutputFormatter;
use Rector\ChangesReporting\Output\GitlabOutputFormatter;
use Rector\ChangesReporting\Output\JsonOutputFormatter;
use Rector\ChangesReporting\Output\JUnitOutputFormatter;
use Rector\CodingStyle\ClassNameImport\ClassNameImportSkipper;
use Rector\CodingStyle\ClassNameImport\ClassNameImportSkipVoter\AliasClassNameImportSkipVoter;
use Rector\CodingStyle\ClassNameImport\ClassNameImportSkipVoter\ClassLikeNameClassNameImportSkipVoter;
Expand Down Expand Up @@ -340,7 +339,6 @@ final class LazyContainerFactory
ConsoleOutputFormatter::class,
JsonOutputFormatter::class,
GitlabOutputFormatter::class,
JUnitOutputFormatter::class,
GitHubOutputFormatter::class,
];

Expand Down
4 changes: 4 additions & 0 deletions src/Parallel/Command/WorkerCommandLineFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ public function create(
}
}

if ((bool) $input->getOption(Option::COMPOSER_BASED)) {
$workerCommandArray[] = self::OPTION_DASHES . Option::COMPOSER_BASED;
}

if ($input->getOption(Option::ONLY) !== null) {
$workerCommandArray[] = self::OPTION_DASHES . Option::ONLY;
$workerCommandArray[] = escapeshellarg((string) $input->getOption(Option::ONLY));
Expand Down
Loading
Loading