Přechod na DressCode

Stará jména pravidel a komentáře fungují dál, konfiguraci přepíše jeden příkaz a vypíše, co se nepřeneslo. Společný postup pro přechod z jakéhokoli nástroje a čestný seznam toho, co bude jinak.

Proč to nebolí

Vím, jak to je. Máte konfiguraci, ve které jsou roky ladění, v kódu stovky phpcs:ignore, možná pár vlastních sniffů a CI, které to všechno spouští. Nástroj se nemění proto, že je nový hezčí. Mění se, když přechod nebolí, a tak je DressCode postavený.

Klíčová věc: DressCode zná pravidla nejen pod svým jménem, ale i pod tím, jak se jmenují v PHP CS Fixeru, PHP_CodeSniffer a Slevomatu. Když napíšete dresscode rules, u každého pravidla vidíte, která cizí jména pokrývá. Z toho plyne všechno ostatní: komentáře v kódu fungují beze změny a konfigurace se dá přeložit strojově.

Postup má tři kroky a každý je vratný.

1. Kód nechte, jak je

Komentáře // phpcs:ignore, phpcs:disable, phpcs:enable, phpcs:ignoreFile i anotace @phpcsSuppress dělají dál to, co dělaly. DressCode je přečte, cizí jméno pravidla přeloží na své a potlačení platí. Do kódu tedy sahat nemusíte a první dresscode check nad projektem můžete pustit hned:

vendor/bin/dresscode check src tests

Bez konfigurace platí preset dresscode/per. Kdo dosud používal @PER-CS nebo PSR12, uvidí zhruba to, co čekal; kdo měl ladění nad rámec standardu, uvidí rozdíly, které vyřeší další krok.

2. Přeložte konfiguraci

Příkaz import přečte cizí konfiguraci a vypíše ekvivalent pro DressCode:

vendor/bin/dresscode import phpcs.xml > dresscode.php
vendor/bin/dresscode import .php-cs-fixer.dist.php > dresscode.php

phpcs.xml je XML a přečte se bez čehokoli dalšího. .php-cs-fixer.dist.php a ecs.php jsou PHP, které se musí spustit, a vracejí objekty cizí knihovny: import na nich funguje jen v projektu, kde je ta knihovna ještě nainstalovaná. Proto konfiguraci překládejte dřív, než starý nástroj odeberete.

Na standardní výstup jde konfigurace, na chybový to, co se přenést nepodařilo:

<?php declare(strict_types=1);

use DressCode\Config;

return Config::create()
	->preset('dresscode/psr12')
	->enable('dresscode/line-length', ['limit' => 100])
	->enable('dresscode/unused-imports', ['searchAnnotations' => false]);

Read 4 rules, enabled 2 and 1 preset.
  No DressCode rule covers Squiz.Commenting.FunctionComment.

Ten druhý seznam je stejně cenný jako první: říká, kde musíte rozhodnout. Pravidlo bez protějšku buď nepotřebujete, nebo si ho napíšete. Sady jako @PSR12 nebo PSR12 se překládají na presety; sady, které preset nemají (třeba @PhpCsFixer), import ohlásí a doporučí začít od dresscode/per.

Přeložené volby přenášejí i hodnoty (lineLimit je limit), ale ne všechny cizí volby mají protějšek; i to import vypíše. Výsledný soubor si projděte, je krátký.

3. Přepište komentáře

Komentáře v kódu fungují i se starými jmény, ale nové jsou kratší a čitelnější. Přepis udělá jeden příkaz:

vendor/bin/dresscode migrate-suppressions src tests

phpcs:ignore SlevomatCodingStandard.Namespaces.UnusedUses se změní na dresscode:ignore dresscode/unused-imports, phpcs:disable a phpcs:enable na dresscode:disable a dresscode:enable, phpcs:ignoreFile na dresscode:ignore-file. Jméno, které žádné pravidlo nepokrývá, zůstane, jak je, a příkaz ho vypíše, takže z výstupu máte seznam potlačení, která už nic nepotlačují.

První oprava

Až konfigurace sedí, pusťte dresscode fix a commitněte výsledek jako samostatný commit bez jiných změn. I když je pravidlo „stejné“, jeho oprava může vyjít o mezeru jinak než u starého nástroje, a projít to řádek po řádku nemá smysl; smysl má vědět, že v tom commitu není nic jiného. U velkého projektu, kde by ten commit byl neúnosný, použijte baseline: dnešní porušení se zapíšou a hlásí se jen nová.

Co bude jinak

Návod, který slibuje bezešvý přechod, ztratí důvěru u prvního rozdílu, tak raději rovnou:

  • Priority neexistují. Kdo si výsledek stavěl na pořadí fixerů, dostane u některých souborů jiný tvar. Pravidla běží opakovaně do ustálení; proč.
  • Pravidlo bez protějšku vypíše import i migrate-suppressions. Není jich málo, hlavně mezi sniffy o dokumentaci a mezi pravidly, která si nástroje překrývají navzájem.
  • Risky pravidla tady nejsou risky. Co PHP CS Fixer zapínal jen na výslovnou žádost, protože nad tokeny nerozeznal bezpečný případ od nebezpečného, rozhoduje tady strom a pravidlo opraví jen bezpečné případy. Naopak pravidlo, které mění chování programu ze své podstaty (strict-comparison dělá z == ===), zůstává vaším rozhodnutím, ať ho zapínáte kdekoli.
  • Exit kódy jsou jiné: 0 čisto, 1 porušení, 2 selhání nástroje. PHP_CodeSniffer i PHP CS Fixer mají vlastní stupnice; skript, který je vyhodnocuje, potřebuje jednu úpravu.
  • Jeden nástroj místo dvou. Kdo kombinoval CodeSniffer a Fixer, měl dvě konfigurace a dva kroky v CI. Teď je jedna a jeden.

Podrobnosti pro konkrétní nástroj: PHP CS Fixer, PHP_CodeSniffer a Slevomat, ECS, Nette Coding Standard.

verze: 1.0