Проблема: 14 комментариев в PR, 13 — про запятые
Вы открываете пулл-реквест коллеги. Сорок файлов изменено, важная фича. А комментарии такие:
«Пропущена пустая строка перед return»
«Тут бы trailing comma»
«Кавычки должны быть одинарными, как во всём проекте»
«Этот импорт не используется»
А в середине диффа — метод, который принимает ?User и дёргает $user->email без проверки на null. Никто не заметил. Все были заняты подсчётом пробелов.
Вот она, настоящая цена отсутствия автоматизации: не само время на мелочи, а внимание, которое не достаётся важному. Плюс человеческий фактор — никому не нравится получать пять замечаний по стилю. Это создаёт напряжение там, где его быть не должно.
Три инструмента решают эту проблему. Тридцать минут на настройку.
1. Pint — ставим точку в спорах о стиле
Pint уже входит в состав новых проектов Laravel. Если проект старый — устанавливается одной командой:
composer require laravel/pint --devЗапуск:
./vendor/bin/pintУтилита приводит весь код к единому стандарту Laravel: кавычки, отступы, порядок импортов, trailing comma — всё без единого человеческого голоса. Если нужно что-то подправить, создаёте pint.json в корне:
{ "preset": "laravel", "rules": { "declare_strict_types": true, "ordered_imports": { "sort_algorithm": "alpha" } } }Два флага, которые пригодятся каждый день:
./vendor/bin/pint --dirty # только изменённые файлы (быстро) ./vendor/bin/pint --test # ничего не меняет, просто сообщает об ошибках--test — то, что идёт в CI.
Важно: сначала выполните Pint на всём проекте в отдельном коммите. Если смешать форматирование с логикой, diff станет нечитаемым, а git blame потеряет смысл.
2. Larastan — баги, которые находятся до деплоя
Larastan — это PHPStan, адаптированный под Laravel. Он анализирует код без запуска и находит ошибки типов, несуществующие методы, потенциально null-переменные.
composer require --dev "larastan/larastan:^3.0"Создайте phpstan.neon в корне:
includes: - vendor/larastan/larastan/extension.neon parameters: paths: - app/ - routes/ level: 5Запуск:
./vendor/bin/phpstan analyseПервая проверка вывалит гору ошибок. Не паникуйте. Начните с уровня 0 или 1, обнулите все ошибки, потом поднимайтесь на уровень выше. Раз в спринт — вполне здоровый темп. Уровень 5 ловит большинство реальных проблем; с шестого начинаются требования docblock'ов.
Если проект большой, есть элегантный выход:
./vendor/bin/phpstan analyse --generate-baselineКоманда сохраняет все текущие ошибки в файл и замораживает их. С этого момента новый код не может добавлять новых ошибок. Старый долг остаётся, но вы выплачиваете его постепенно.
Что Larastan находит, а код-ревью часто пропускает:
// Larastan: «Cannot call method email() on User|null» $user = User::find($id); Mail::to($user->email)->send(...); // 💥 в проде если пользователь не найден // Larastan: «Call to an undefined method App\Models\Pedido::pagos()» Pedido::pagos()->get(); // переименовали скоуп, а тут забылиВторой пример — золото при рефакторинге.
3. Rector — рефакторинг на автомате
Rector переписывает код за вас. Незаменим при обновлении версий PHP или Laravel, когда не хочется вручную править сотни файлов.
composer require rector/rector --devrector.php в корне:
<?php use Rector\Config\RectorConfig; return RectorConfig::configure() ->withPaths([ __DIR__ . '/app', __DIR__ . '/tests', ]) ->withPhpSets() // подгоняет под версию PHP ->withPreparedSets(deadCode: true) // удаляет мёртвый код ->withComposerBased(laravel: true); // правила LaravelВсегда запускайте сначала в режиме сухого прогона:
./vendor/bin/rector --dry-run # показывает, что будет сделано ./vendor/bin/rector # применяет измененияЧто Rector делает сам: конвертирует старый конструктор в property promotion, заменяет array() на [], упрощает if/else в тернарник, добавляет типы возврата, удаляет неиспользуемые use, обновляет устаревшие вызовы Laravel.
Одна «ректорная» пятница в легаси-проекте экономит недели ручной работы. Два правила: напишите тесты и делайте отдельный коммит — как с Pint.
Автоматизируем проверки
Инструменты бесполезны, если их запускают вручную. Привяжите их к CI и pre-commit.
В CI — джоба, которая не пропускает нарушителей:
quality: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: '8.4' - run: composer install --prefer-dist --no-interaction - run: ./vendor/bin/pint --test - run: ./vendor/bin/phpstan analyse --error-format=githubОбратите внимание: Rector здесь нет. Он — для точечного рефакторинга, а не для непрерывной валидации. Держите его вне CI.
Pre-commit hook, чтобы ошибка не дошла до коммита:
# .git/hooks/pre-commit #!/bin/sh ./vendor/bin/pint --dirty git add $(git diff --name-only --cached | grep '\.php$')Этот хук форматирует только изменённые файлы и добавляет их обратно в коммит. Вы больше никогда не закоммитите код мимо стандарта — и даже не заметите этого.
Но помните: инструменты не заменяют ревью
Pint, Larastan и Rector не оценят, удачно ли назван класс, корректна ли бизнес-логика, не упадёт ли запрос на 100 тысячах записей и не создали ли вы дыру в авторизации.
Они лишь убирают шум, чтобы ревьювер сосредоточился на том, что умеет только человек. А это именно то, что нужно.
Бонус: одна команда для всего
Добавьте в composer.json и забудьте:
"scripts": { "qa": [ "./vendor/bin/pint", "./vendor/bin/phpstan analyse", "php artisan test" ] }Теперь перед каждым PR достаточно набрать composer qa. ✅
Напоследок
Цель не в идеальном коде, а в том, чтобы перестать тратить человеческое внимание на то, что решает машина.
Если есть время только на один шаг — установите Pint. Две команды — и результат сразу: в следующем ревью никто не напишет комментарий про запятую.
Ваш проект уже пользуется чем-то из этого? А какая самая нелепая ошибка, которую нашёл PHPStan? Расскажите в комментариях — самые смешные обычно в файлах, которые «работали три года без проблем».
Комментарии (0)
Войдите, чтобы комментировать.
Пока нет комментариев. Будьте первым.