Локальные и контейнерные окружения нельзя смешивать
Симптом
В Zed language server Ruff постоянно сбрасывал соединение и не запускался.
Ошибка указывала, что бинарник Ruff не может быть выполнен.
Контекст
Один и тот же каталог проекта использовался и локальными инструментами, и проверками внутри Linux-контейнера, который нужен для запуска ralphex. При запуске проверок в контейнере в общий virtualenv попал Linux-бинарник Ruff. macOS-инструмент редактора затем пытался запустить его как локальную команду.
Корневая причина
Virtualenv был привязан к платформе, но использовался как будто он переносим между локальной macOS-средой и Linux-контейнером. В результате Zed получил бинарник другой операционной системы.
Ошибочное предположение
Я предполагал, что virtualenv можно безопасно переиспользовать между двумя окружениями, если они работают с одним исходным кодом. Исходный код общий, но бинарные зависимости и инструменты окружения - нет.
Обнаружение
Сигналом был stderr language server: бинарник Ruff существовал по ожидаемому пути, но операционная система не могла его выполнить. Проверка архитектуры бинарника и владельца virtualenv должна быть частью диагностики таких сбоев.
Исправление
Я создал два независимых virtualenv:
- локальный - для редактора и запусков на macOS;
- контейнерный - для запуска ralphex и проверок внутри Linux.
Общие исходники не означают, что окружение с бинарными зависимостями тоже должно быть общим.
Проверка
Нужно проверять запуск Ruff из каждого окружения отдельно и убедиться, что Zed использует локальный interpreter, а контейнерные проверки - свой. В CI полезно проверять, что virtualenv не пересекается с каталогом, который монтируется между разными операционными системами.
Общий вывод
Virtualenv и другие каталоги с бинарными зависимостями принадлежат конкретной платформе. Между host и container следует разделять не только процессы, но и окружения инструментов, даже если исходный код проекта общий.