На одном из проектов добавил composer dependency analyser (писал про него тут) и он мне выдал, что у меня в зависимостях два неиспользуемых пакета:
•
phpdocumentor/type-resolver•
symfony/property-accessУдалил их, проверил статанализом — всё хорошо. Тесты покрывают не весь проект, но те, что были — тоже прошли успешно. Ну и отлично, подумал я 🙂
А дальше внезапно пошли ошибки:
Unable to use the "Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor" class as the "phpdocumentor/type-resolver" package is not installed. Try running composer require "phpdocumentor/type-resolver".
Оказалось, что в проекте используется класс
PhpStanExtractor из пакета symfony/property-info, которому для работы нужен пакет phpdocumentor/type-resolver. В коде у них добавлена проверка на существование класса ContextFactory из этого пакета:public function __construct(…)
{
if (!class_exists(ContextFactory::class)) {
throw new \LogicException(…);
}
…
}
Аналогичная ситуация и с пакетом
symfony/property-access — он требуется классу ObjectNormalizer из symfony/serializer.Понятно для чего это сделано — чтобы не тянуть лишние зависимости для ситуаций, когда конкретно
PhpStanExtractor и ObjectNormalizer в проекте не используются.Но на практике это приводит к описанной проблеме, когда требуемую зависимость можно случайно удалить, будучи уверенным что, она не используется 🤷♂️
❓ Может быть стоит отказаться от опциональных зависимостей в библиотеках и делать пакеты с явными зависимостями?
Да, будет больше пакетов и будет менее удобно их разрабатывать, но зато мы получаем надёжное управление зависимостями. До этого случая я более нейтрально относился к опциональным зависимостям, и в Yii3 они кое-где встречаются, но сейчас весы качнулись.
🤓 Как защититься от подобных ситуациях на уровне проекта?
Конечно же, тесты. Хотя бы дымовыми тестами стоит покрыть все маршруты, это уже сильно повысит процент выявления проблем. В моём случае, это точно помогло бы.