Začínáme s DressCode

Za pět minut máte nástroj nainstalovaný, projekt zkontrolovaný a většinu nálezů opravenou. Projdeme instalaci, příkazy check a fix, volbu stylu podle PER Coding Style 3.1 nebo Nette a konfigurační soubor, který pak stačí commitnout.

Instalace

DressCode je nástroj, ne knihovna, takže ho můžete nainstalovat mimo projekt, který kontroluje. Nejjednodušší je globální instalace:

composer global require dresscode/dresscode

Adresář s globálními binárkami Composeru přidejte do proměnné PATH a příkaz dresscode je pak k dispozici odkudkoli.

Do průběžné integrace, kde chcete verzi nástroje přibít na konkrétní číslo, se hodí instalace jako samostatný projekt:

composer create-project dresscode/dresscode temp/dresscode
temp/dresscode/bin/dresscode check

A do třetice: DressCode lze přidat jako vývojovou závislost projektu (composer require --dev dresscode/dresscode) a spouštět z vendor/bin/dresscode. Tuhle cestu chcete, jakmile máte v projektu i PHPStan: DressCode se ho pak ptá na typy kódu a dokáže třeba přepsat zastaralé API knihoven podle toho, čím proměnná opravdu je, viz Typy z PHPStanu. Počítejte jen s tím, že DressCode vyžaduje PHP 8.4 až 8.6, takže by na jedné z těchto verzí musel běžet i váš projekt, i kdyby mu jinak stačilo starší PHP.

To je totiž věc, která se plete nejčastěji: verze PHP, na které běží nástroj, a verze PHP, pro kterou je psaný váš kód, jsou dvě různá čísla. Když je DressCode nainstalovaný mimo projekt, může běžet třeba na PHP 8.5 a přitom kontrolovat kód psaný pro PHP 8.1. Cílovou verzi si přečte z composer.json vašeho projektu a pravidla se jí řídí, takže vám do kódu nikdy nenapíše syntaxi, kterou by projekt neuměl přeložit. Platí to od PHP 8.0; starší verze DressCode nepodporuje a upozorní na to.

Víc DressCode nepotřebuje: parser a strom, na kterých stojí, jsou samostatná knihovna PhpSyntax bez jediné závislosti, k tomu čtyři malé balíčky z Nette, parser phpDocu od PHPStanu a porovnávač verzí od Composeru. Žádný framework.

Kontrola kódu

DressCode nemá vlastní styl, a proto bez konfigurace nezačne: kdyby tiše sáhl po jednom ze standardů, první fix by v projektu psaném jinak přepsal skoro každý řádek. Nejrychleji mu styl řeknete tak, že ho necháte změřit z kódu, který už máte:

dresscode init

Příkaz změří na vzorku souborů odsazení, uvozovky a tvar podmínek a zapíše do kořene projektu dresscode.neon; podrobnosti najdete v popisu příkazu init. Od té chvíle stačí dresscode check. Kdo chce nástroj jen vyzkoušet a nic nezakládat, zvolí standard přepínačem --preset a vyjmenuje cesty:

dresscode check src tests --preset perCs

Výstup vypadá takhle:

DRESS|CODE 1.0.0
Config     none, preset perCs
Target     PHP 8.2 from `composer.json`
Checking   214 files in /var/www/shop

src/Cart.php
  error   8:12  A line break before the opening brace                       bracesPosition
  error   9:25  An array must be written with the short syntax              shortArraySyntax
  error  10:21  No whitespace after the opening parenthesis                 parenthesesSpacing
  error  11:11  At least one space before the `==` operator                 binaryOperatorSpacing
  error  11:19  The body of a control structure must be enclosed in braces  controlStructureBraces
...

FOUND  36 violations, a fix leaves 1 in 12 of 214 files

Každý řádek říká, kde problém je (řádek a sloupec), co je špatně (zpráva popisuje, jak má kód vypadat) a které pravidlo to hlásí. Jméno pravidla vpravo je to, s čím se dá dál pracovat: nechat si ho vysvětlit i s jeho volbami (dresscode explain bracesPosition), najít ho v přehledu pravidel, nastavit nebo vypnout anebo potlačit na jednom místě.

Hlavička nahoře odpovídá na dvě otázky, které jinak stojí za polovinou nedorozumění: podle čeho se kontroluje (konfigurační soubor a presety) a pro jakou verzi PHP. Shrnutí dole navíc prozradí, kolik porušení by nechal automatický fix.

Exit kódy jsou čtyři a stojí za zapamatování, protože na nich stojí kontrola v průběžné integraci:

kód význam
0 čisto
1 nalezená porušení, soubor, který nejde parsovat, nebo víc varování, než dovolí --max-warnings
2 některý soubor se nepodařilo zpracovat (pravidlo selhalo, opravy se neustálily, soubor se mezitím změnil) nebo nástroj selhal za běhu
3 chyba na příkazové řádce nebo v konfiguraci, třeba neznámé pravidlo

Automatická oprava

Většinu nálezů opraví DressCode sám. Před prvním během si soubory commitněte nebo aspoň mějte čistý pracovní strom, ať v diffu vidíte přesně to, co nástroj změnil:

dresscode fix
src/Cart.php  rewritten
src/Order.php  rewritten
  error  14:21  The method `get_total` must be written in camelCase  nameCasing
...

FIXED  36 violations found, 1 remaining in 12 of 214 files

Každý soubor, který fix změnil, má ve výpisu poznámku rewritten. Pod ním stojí, co opravit nejde (třeba jméno metody, které by se muselo změnit i všude, kde se metoda volá): zůstane to jako error a exit kód bude 1, jinak 0. Shrnutí řekne, kolik porušení se našlo a kolik jich zbylo. Kdo chce opravy napřed vidět, pustí dresscode check --diff: ukáže, co by fix změnil, a nic nezapíše.

Opravu udělejte jako samostatný commit bez jiných změn. Je to jeden z těch commitů, které nikdo nečte řádek po řádku, a přesně tak má vypadat: git blame pak vede na něj a ne na váš další commit se skutečnou změnou. Po commitu může zůstat pár porušení, která za vás opravit nejde; kdyby jich bylo víc, než zvládnete hned, zapíše je baseline a hlásit se budou jen nová.

Druhé spuštění je rychlejší než první: DressCode si pamatuje obsah souborů, které prošly čistě, a pokud se nezměnil ani obsah, ani konfigurace, nezpracovává je znovu.

Přechod na novější PHP

DressCode kód nejen formátuje, ale i přepisuje na novější PHP. Když v composer.json zvednete require.php a přidáte jedním řádkem groups: [modernization], začnou pravidla té skupiny psát, co nová verze přinesla, a ve stejném běhu to zformátuje váš standard. Žádný standard tuhle skupinu nenese sám: přepsat kód na novější PHP je věc, kterou si pustíte, až ji chcete:

return $article === null ? null : $article->getAuthor();
return $article?->getAuthor();

Takhle to jde od PHP 8.0 až po PHP 8.6, které teprve vyjde. Co všechno se přepíše a jak na přechod v praxi, popisuje Přechod na novější PHP; převod kódu při aktualizaci Nette a dalších knihoven Aktualizace knihoven.

Konfigurace v NEONu

Konfigurace projektu je soubor dresscode.neon v jeho kořeni. Ten, který zapíše dresscode init, můžete dál upravovat, nebo si ho napsat sami. Takhle vypadá ten nejjednodušší:

presets:
	- nette

paths:
	- src
	- tests

Je to NEON, tedy formát, který znáte z konfigurace PHPStanu, a klíče jsou schválně podobné: paths, excludePaths. Kdo má radši PHP, napíše totéž do dresscode.php jako new Config(...) s pojmenovanými argumenty; oba zápisy umějí totéž.

Vedle presets stojí klíč groups, kterým řeknete, co po kódu chcete kromě vzhledu: cleanup uklidí, co je v kódu pro nic, modernization přepíše kód na novější PHP, deprecations na nové API knihoven. Skupin je celkem šest a popisuje je Konfigurace.

Do téhož souboru přijdou i jednotlivá pravidla s volbami a výjimky pro cesty; všechno popisuje stránka Konfigurace. A protože pár řádků konfigurace znamená přes sto pravidel z několika vrstev, vypíše dresscode config, co z nich nakonec platí a odkud se každá hodnota vzala.

Kam dál