W ostatnich dniach został wydany Laravel Pint i wywołał ambiwalentny zamęt – niektórzy go uwielbiają, inni nienawidzą 😉. Osobiście mam co do niego mieszane uczucia i chciałem podzielić się swoimi przemyśleniami na ten temat.

Uznanie i podziw

Na wstępie chciałbym podkreślić mój podziw dla pasji Nuno Maduro. Jest naprawdę oddany społeczności Open Source, głównie części związanej z Laravelem, i wciela swoje pomysły w życie, dostarczając narzędzia dla wielu ludzi w świecie PHP. To naprawdę niesamowite.

Chodzi o to, że z jego ostatnim projektem nie jest mi po drodze i chciałbym tutaj poddać pod dyskusję kilka zagadnień.

A teraz coś z zupełnie innej beczki

Pint wskazuje na CS Fixer

To pierwsza rzecz, która mnie poruszyła: tweet Nuno ogłasza nowy pakiet, narzędzie do naprawy kodu, które nie ma żadnych dodatkowych zależności. Nie ma żadnej wzmianki o PHP CS Fixer, czyli właściwym narzędziu, na którym został zbudowany Pint. Oczywiście jest o tym informacja w readme, ale nie oszukujmy się – na pewno nie przeczytała tego duża część odbiorców ogłoszenia. Wyraźne podkreślenie tego w ogłoszeniu byłoby uczciwe wobec twórców PHP CS Fixera i jego opiekunów…

Zwłaszcza, że Pint nie wnosi zbyt wiele w kwestii nanoszenia poprawek – stawia na Developer Experience.

Długoletnie czekanie się skończyło

Widziałem wiele tweetów, w których ludzie piszą, że „szukali tego”, np.:

Byłem dość zdezorientowany. Gdzie dokładnie szukali ci ludzie? W dokumentacji Laravela?

Oczywiście nie jest to wina Nuno, że ludzie w społeczności Laravela nie znają podstawowych narzędzi, które są obecne w świecie PHP od lat. To po prostu smutne, że ludzie nie szukają istniejących, sprawdzonych w boju rozwiązań dalej niż w zbiorze laravel/*. Byłoby lepiej, gdyby wszyscy ci, którzy tego “szukali”, dostali w ogłoszeniu jawną informację na ten temat i dowiedzieli się o istnieniu tego typu narzędzi.

Rozumiem jednak, że nie leży to w interesie Laravela…

Subiektywnie świetny DX

Jedną z najbardziej reklamowanych funkcji Pinta jest interfejs użytkownika CLI. Ogłoszenie zawierało ładny, prosty zrzut ekranu przedstawiający wynik działania polecenia. Jednak moim zdaniem komendy CLI przede wszystkim powinny być przydatne i w pewnym momencie Pint traci tę cechę:

Laravel Pint: Zbyt dużo reguł

@TattedTechBro, Twitter

Lista zastosowanych reguł jest prezentowana poziomo w jednym wierszu, więc jeśli zastosowano wiele fixerów, lista może zostać przycięta i nie będziesz wiedział, które zostały użyte. Dla osób oczekujących fikuśnych wyników, a nie rzeczywistych ważnych danych, prawdopodobnie nie będzie to problemem. Osobiście, patrząc na powyższy zrzut ekranu, widzę niechlujny blok tekstu z utraconymi niektórymi informacjami. Dla mnie nie jest to przewaga nad zwykłym rezultatem CS Fixera (a przynajmniej w tym momencie, bo jest to wciąż wersja 0.* i wiele może się jeszcze zmienić).

Zero zależności, niezerowa ilość problemów

Pint jest budowany za pomocą Laravel Zero, co oznacza, że jest dostarczany jako samowystarczalny plik wykonywalny, który zawiera wszystkie swoje zależności. Na pewno to minimalizuje ryzyko wystąpienia konfliktów Composera, ale miejcie proszę na uwadze, że takie podejście ukrywa faktyczną zależność do PHP CS Fixera. Zainstalujesz to, co jest wbudowane w Pint, a nie to co jest faktycznie dostępne w Packagist. Efektywnie oznacza to, że aby skorzystać z poprawek lub nowych funkcjonalności CS Fixera, musi zostać wydana nowa wersja Pint. To jest zupełnie inna sytuacja niż w przypadku PHPStan czy Rectora, które również dostarczane są z podejściem “zero zależności” (jako plik PHAR lub prefiksowane, wbudowane vendory) - to są narzędzia wysokiego poziomu, podczas gdy Pint to nakładka na właściwe narzędzie.

Czasami można czuć pokusę, by zainstalować Pint globalnie, jak sugeruje wiele ludzi:

Stop. Nie rób tego 😉. Każdy projekt powinien mieć swój własny, jawnie określony zestaw zależności w konkretnych wersjach, tak by każdy developer mógł zainstalować dokładnie ten sam zestaw narzędzi i pracować w identyczny sposób.

Twój kod, Twoje zasady

Inną przereklamowaną funkcją Pinta jest „zero konfiguracji”. Ludzie są zachwyceni, że „to po prostu działa!”.

Pozwólcie, że zapytam: czy wszystkie te ponad 400 problemów ze stylizacją były rzeczywiście naruszeniami? Cóż, to zależy. Jeśli używasz podejścia „zero konfiguracji”, oddajesz kontrolę nad swoimi standardami kodowania na rzecz narzędzia. To nie jest twój standard kodowania. Może to prowadzić do sytuacji, w których kod, który lubisz, musi zostać zmieniony, aby zadowolić narzędzie. Oczywiście nie musisz stosować wszystkich poprawek i możesz skonfigurować PHP CS Fixer Pint, więc niektóre reguły mogą być wyłączone lub zachowywać się inaczej. Tylko wtedy to już nie jest zero-config, więc czy naprawdę ta cecha Pinta zasługuje na taką emfazę?

Moim zdaniem dobrze jest mieć jawną konfigurację. To gwarantuje, że zachowanie będzie dokładnie takie, jakie chcesz, a nie takie, jakie twórca narzędzia nakładki dostarczył jako domyślne. Jest to szczególnie ważne w początkowym okresie rozwoju (wersja 0.*), kiedy nie masz żadnej obietnicy wstecznej kompatybilności.

Zautomatyzuj to: tak, ale nie!

Ostatnią rzeczą, na którą chciałbym zwrócić uwagę, jest automatyzacja CS. Widziałem wiele tweetów na temat integracji Pinta z Github Actions:

Przedyskutowałem to w kilku tweetach (np. tutaj), ale to jest poza kontrolą. Dlatego chciałbym tutaj podkreślić, że automatyzacja sprawdzania CS jest wysoce zalecana, ale automatyzacja poprawek CS nie. Narzędzia CS powinny być częścią codziennej pracy deweloperskiej (nawyki CLI, pre-commit hook w Git, zadanie w #CI) i sprawdzać, czy kod jest zgodny ze zdefiniowanym standardem.

Jeśli sprawdzenie się nie powiedzie, możesz zdecydować, czy każde naruszenie powinno zostać naprawione, czy też reguła powinna zostać wyłączona/inaczej skonfigurowana. W pewnym momencie być może zaufasz narzędziu na tyle, aby umożliwić automatyczne poprawki, ale osobiście tego nie robię. Zwłaszcza w dużych, starszych aplikacjach, w których standardy nie są w pełni stosowane, może to prowadzić do niezamierzonej zmiany logiki kodu (np. CS Fixer może zmienić == na === gdy włączone są ryzykowne reguły), co spowoduje problemy dla użytkowników.

Pamiętaj, narzędzia to tylko narzędzia, robią to, do czego zmusili je programiści. Niektóre scenariusze lub przypadki brzegowe mogą nie zostać przetestowane lub po prostu mogą być źle zaimplementowane. Nie traktuj wyników takich narzędzi jako w 100% bezpiecznych.

Ostateczna decyzja należy do Ciebie

Powiedziawszy powyższe, możemy zgodzić się, że ostatecznie to od Ciebie zależy, co pasuje do Twoich potrzeb. Możesz używać dowolnego narzędzia, ale rób to odpowiedzialnie i świadomie. Doceń i wspieraj ludzi ciężko pracujących nad narzędziami, których używasz, takich jak Dariusz “keradus” Rumiński, twórca i opiekun PHP CS Fixera, który napędza Laravel Pint.