Rector to narzędzie, które umożliwia automatyczną refaktoryzację kodu. ECS to z kolei narzędzie do automatyzacji standardów kodowania. Od niedawna ich konfiguracja jest dużo bardziej przyjazna.

O #Rectorze i #ECS na tym blogu będzie jeszcze zapewne nie raz, bo to narzędzia, które są po prostu świetne. Teraz jednak chciałbym się skupić na bardzo przyjemnej zmianie, jaka została wprowadzona do nich w ostatnich dniach.

Kontekst historyczny

Jako że oba te narzędzia pod maską korzystają z symfony/dependency-injection, przez długi czas były zmuszone do poruszania się w obrębie API udostępnianego przez ten komponent, dlatego że wiele jego klas lub metod oznaczonych jest jako final i nie umożliwia rozszerzania. Wszystko zmieniło się, gdy Rector wdrożył podział na repozytorium deweloperskie i tzw. “prefiksowane”, którego zawartość jest wynikiem automatycznej refaktoryzacji kodu… z użyciem Rectora 😉 To podejście otworzyło wiele nowych możliwości, z których autorzy skrzętnie korzystają, patchując oryginalne komponenty Symfony przykrywając ich oryginalne API swoim własnym.

Geneza zmian w API

Używając Rectora w pewnym momencie natknąłem się na problem dotyczący konfiguracji narzędzia w kontekście #statycznej analizy, więc rozpocząłem dyskusję, której owocem był mój Pull Request. Finalnie nie został zmerdżowany w tej formie, ale stał się bazą do faktycznych zmian w API, które wprowadził sam autor, Tomas Votruba. Jak sam stwierdził, mój pomysł odkrył przed nim nowy wszechświat opcji 😅

Stare kontra Nowe

Zmiana w API nie jest rewolucją, ale bardzo przyjemną ewolucją. Wcześniej konfigurowanie wyglądało następująco:

use Rector\Core\Configuration\Option;
use Rector\Php74\Rector\Property\TypedPropertyRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $parameters = $containerConfigurator->parameters();
    $parameters->set(Option::PARALLEL, true);
    $parameters->set(Option::AUTO_IMPORT_NAMES, true);

    $services = $containerConfigurator->services();
    $services->set(TypedPropertyRector::class);
};

Natomiast po zmianach zamiast konfiguratora Symfony dostępny jest dedykowany konfigurator Rectora:

use Rector\Php74\Rector\Property\TypedPropertyRector;
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig->parallel();
    $rectorConfig->importNames();

    $rectorConfig->rule(TypedPropertyRector::class);
};

Analogiczne zmiany zostały wprowadzone w ECS, gdzie końcowe API oczywiście jest ciut inne niż w Rectorze, ale zasada jest ta sama — dostępne są dedykowane metody do konfiguracji narzędzia, zamiast zbyt ogólnego $containerConfigurator->parameters()->set().

Moja propozycja uproszczenia ECS API

Osobiście szybko wdrożyłem zmiany do projektów, w których używam Rectora i ECS, ale modyfikując ecs.php zwróciłem uwagę na to, że API udostępnia 2 dedykowane metody do dodawania reguł: rule() oraz ruleWithConfiguration(). Osobiście uznałem, że jest to niewygodne i utworzyłem Pull Request z propozycją uproszczenia API. Niestety, propozycja została odrzucona, choć osobiście nie zgadzam się z argumentacją 😉

A Wy, jak uważacie?