Laramago: как я учу Mago понимать Laravel

Содержание
  1. Зачем я его делаю
  2. Как он создавался
  3. Что есть сейчас
  4. Обновление от 16 октября: первые замеры
  5. Как это соотносится с уровнями PHPStan
  6. Что буду ускорять
  7. Почему до версии 1.0 ещё девять проектов

Продолжаю рассказывать о своих проектах. Сегодня — Laramago, пакет для проверки Laravel-кода с помощью Mago. Уже вышла версия 0.1.5. Расскажу, откуда он появился, что умеет и почему для версии 1.0 мне нужны десять реальных проектов.

Laramago — Mago для Laravel: ноутбук с кодом, дерево разбора, лупа с выделенной проблемой и секундомер для замеров
Laramago: проверки, замеры и оптимизация. Иллюстрация.

Зачем я его делаю

Хочется замечать ошибки ещё во время разработки. Mago умеет проверять PHP-код, находить проблемы с типами и форматировать файлы. Но у Laravel много своей магии: свойства моделей, связи, цепочки запросов, контейнер зависимостей. То, что привычно разработчику, анализатору нужно объяснить.

Для этого я и делаю Laramago. Хочу, чтобы проверки понимали устройство моих Laravel-проектов и помогали разбирать настоящие ошибки.

Как он создавался

Начал с Laravel-пресета и подключения через Composer. В первом релизе 0.0.1 уже были настройки линтера, форматирования и начальная поддержка вызовов Eloquent.

Постепенно добавлял сведения о свойствах моделей, связях, scopes, построителях запросов, коллекциях и конфигурации. Сценарии проверяю через сам Mago; поведение также сравниваю с Larastan. Если особенности приложения определить не удалось, важно сохранить диагностику, а не объявить код правильным.

Что есть сейчас

Пакет уже доступен на Packagist и используется в одном реальном проекте. Основной анализ читает исходники без запуска Laravel и подключения к базе. Это помогает работать со свойствами и связями моделей, уточнять типы результатов запросов и проверять поддерживаемые конструкции фреймворка.

В 0.1.5 добавил необязательный сборщик сведений о схеме базы для выбранных моделей. Пока он работает только с SQLite в файле и включается отдельно, с выполнением кода приложения. Одновременно улучшил проверку актуальности метаданных и исправил предупреждения в коде пакета.

Это рабочий предрелиз: возможностей уже немало, но опыт на разных приложениях ещё предстоит набрать.

Обновление от 16 октября: первые замеры

Проверил связку Mago и Laramago на одном реальном Laravel-приложении: 531 PHP-файл, около 102 тысяч строк. Название и код приложения оставляю за кадром. Сравнил её с PHPStan и Larastan, а также с Mago без расширений.

Для каждого варианта сделал прогрев и три измеряемых полных запуска в Linux с двумя CPU и лимитом памяти контейнера 6 ГиБ. Порядок инструментов менял между раундами. vendor был доступен только для чтения. PHPStan работал на уровне 10 с очищенным списком исключений конфигурации; аннотации в исходниках и остальные настройки проекта сохранялись. Кеш результатов PHPStan перед каждым запуском был пустым, дисковый кеш системы не очищал.

ВариантМедианаДиапазон трёх запусков
Mago + Laramago 0.1.5415,83 с405,72–524,25 с
PHPStan + Larastan, уровень 1069,37 с54,99–73,67 с
Mago без расширений7,77 с7,60–7,78 с

В этой серии Laramago заметно медленнее PHPStan с Larastan. Это результат на одном приложении и одной машине, с разными наборами проверок. Количество сообщений тоже нельзя превращать в счёт найденных ошибок: у инструментов различаются правила и уровни важности. По трём запускам универсальный рейтинг скорости не построить.

Как это соотносится с уровнями PHPStan

Глубину проверял отдельно от времени — на открытом наборе из 33 пар «ошибка и исправленный вариант», прогнав уровни PHPStan от 0 до 10 и Mago с расширением и без него. Поэтому назвать Laramago аналогом одного конкретного уровня PHPStan не могу.

Связка Mago и Laramago обнаруживает выбранные ошибки с mixed, которые в этом наборе появляются у PHPStan на уровнях 9 и 10. Но в проверенном режиме analyze пропускает три примера с отсутствующими аннотациями типов, которые PHPStan отмечает с уровня 6. Недостижимый код Mago в выбранном примере относит к подсказкам, а PHPStan — к ошибкам. Совпадение на отдельных примерах ещё не означает одинакового покрытия всего приложения.

Что буду ускорять

В отдельном диагностическом запуске увидел частые вытеснения деревьев разбора из кеша. У одного из двух обработчиков суммарный объём уникальных сериализованных деревьев составил около 132 МиБ при лимите кеша 64 МиБ; примерно 93,5% обращений завершились промахом. Эти данные относятся только к одному обработчику и пока не показывают, какую долю общего времени можно сэкономить.

Дальше хочу проверить ёмкость кеша и порядок обработки файлов, уменьшить повторный разбор исходников. Ускорение буду оценивать на полных запусках вместе с памятью и сохранением диагностики. Успешного ускорения всего анализа пока не заявляю.

Методика, полная матрица проверок и результаты замеров доступны в репозитории Laramago. Там же есть открытые примеры и скрипты для повторения проверок.

Почему до версии 1.0 ещё девять проектов

У меня простая схема версий. В 0.1.5 первая цифра 0 означает предрелиз, вторая 1 — число реальных проектов, где Laramago запущен, а третья 5 — патч-версию.

Когда Laramago заработает на десяти реальных проектах, выпущу 1.0. Для меня это будет основанием сказать: пакет проверен в работе на разных приложениях. Пока продолжаю подключать его к проектам, находить ограничения и исправлять их.

Описание и ссылки собрал на странице Laramago. Исходники — на GitHub, пакет — на Packagist. О следующих шагах буду писать под меткой Laramago.

Есть что добавить?

Ваш email не публикуется. Обязательные поля отмечены *