Перейти к содержанию

Участие в разработке

Собирать через make, а не голым cargo

Ловушка, которая обходится дороже всего

Makefile получает каталог тулчейна из rust-toolchain.toml через rustup which и ставит его первым в PATH. Голый cargo может оказаться тем, что постарее, из Homebrew, — и тогда у «у меня зелено, в CI красно» появляется объяснение, которое никому не нравится искать.

rustup run 1.92.0 rustc --version
rustup run 1.92.0 cargo --version

Цели

Команда Что делает
make build собрать workspace и bugsaurtarget/debug/bugsaur
make check только проверка типов; бинарники после неё запускать нельзя
make fmt проверить форматирование; ничего не меняет
make clippy clippy по workspace с -D warnings
make test offline-набор тестов, --no-fail-fast
make test-one одна цель: PKG=<крейт> [TEST=<файл>] [NAME=<фильтр>]
make fixture-rust собрать Rust-фикстуру
make fixture-c / make fixture-cpp собрать фикстуры C и C++
make gui / make gui-rust собрать и запустить GUI на фикстуре
make gui-c / make gui-cpp собрать и запустить GUI на C- или C++-фикстуре
make serve SOCKET=… поднять бэкенд без окна
make clean удалить артефакты сборки Cargo
make help перечислить все цели

Цели сайта документации:

Команда Что делает
make docs-deps создать venv документации и поставить закреплённые зависимости
make docs-build собрать сайт с --strict
make docs-serve поднять сайт локально с live reload
make docs-check проверить совпадение состава EN- и RU-страниц

Запуск одного теста

Прогон всего workspace долгий, а зависший тест делает его бесполезным:

make test-one PKG=php-dbgp-adapter TEST=protocol
make test-one PKG=bugsaur NAME=every_entry_point

Как не раздувать кэш Cargo

target/ можно удалять целиком. В этом workspace он способен вырасти до десятков гигабайт: там накапливаются отладочные символы, incremental-состояния и отдельные наборы артефактов для каждого бинарника, интеграционного теста и сочетания features. Cargo не обязательно удаляет варианты, которые уже не нужны.

После make clean нельзя прогревать кэш через --all, --workspace или --all-targets. В частности, не запускайте эти команды только ради заполнения target/:

cargo build --all
cargo test --workspace
cargo clippy --workspace --all-targets

Они собирают цели, которые могут ни разу не понадобиться в обычной разработке: GUI-харнессы, все интеграционные и E2E-тесты. Так быстро возвращается объём, ради которого и выполнялась очистка. Полные команды workspace по-прежнему нужны, когда важен их результат, например перед pull request или в CI, но использовать их для прогрева кэша не следует.

Пусть обычная работа пересобирает только необходимое. Чтобы подготовить основное приложение, используйте закреплённый тулчейн и соберите только bugsaur:

RUSTC="$(rustup which rustc --toolchain 1.92.0)" \
  rustup run 1.92.0 cargo build -p bugsaur --locked --offline

Для проверки типов и тестов сохраняйте такую же узкую область:

RUSTC="$(rustup which rustc --toolchain 1.92.0)" \
  rustup run 1.92.0 cargo check -p bugsaur --locked --offline
make test-one PKG=bugsaur NAME=<фильтр-теста>

cargo clean удаляет сгенерированные артефакты сборки, но не скачанные крейты в глобальном кэше Cargo. Первая сборка будет холодной и может занять заметное время; последующие сборки автоматически создадут полезный incremental-кэш.

Живые тесты адаптеров

По умолчанию ignored, потому что им нужны настоящие установленные тулчейны:

make live-codelldb      # настоящий codelldb по TCP DAP
make live-codelldb-c    # C, тот же адаптер, своя фикстура
make live-codelldb-cpp  # C++, STL-контейнеры в панели переменных
make live-dlv-100k      # пагинация коллекции из 100k элементов через Delve
make live-debugpy       # Python, нужен debugpy в venv фикстуры
make live-php-docker    # PHP/Xdebug в Docker
make live-test-rust     # тест под курсором, Rust
make live-test-php      # тест под курсором, PHP

Для live-debugpy интерпретатор по умолчанию берётся из venv фикстуры, потому что debugpy ставится в окружение, а не в систему:

python3 -m venv fixtures/python-hello/.venv
fixtures/python-hello/.venv/bin/pip install debugpy

Готовое окружение задаётся через BUGSAUR_PYTHON.

Приёмочные сценарии:

make test-m8     # гейт workspace, fake-адаптер, фикстуры, живые сценарии
make test-m10    # приёмка PHP / Xdebug

Правило offline

make build, make check и make test работают с --locked --offline. Сборка, которая молча лезет в сеть, — это сборка, которая ведёт себя иначе на машине без сети. И в CI.

CI

ci.yml гоняет гейт workspace на macOS и Linux одновременно. Одной ОС недостаточно: unix-сокеты, права 0600 и поведение при закрытии соединения различаются, а весь слой IPC на них и держится.

Тулчейн явно не ставится — rustup на раннере читает rust-toolchain.toml и сам доустанавливает закреплённую версию вместе с rustfmt и clippy. Закреплённый здесь action на stable приводил к тому, что CI уезжал вперёд относительно локальной сборки.

docs.yml отдельный и собирает сайт документации. От Rust-тулчейна он не зависит и удлинять матрицу тестов не должен.

Каждый прогон ci.yml также публикует в секции Artifacts этого run оптимизированные по размеру архивы для Linux x86-64, macOS Intel и macOS Apple Silicon. Это короткоживущие сборки для проверки коммита, а не способ установки. Отправленный тег v* запускает release.yml и публикует тот же набор платформ в GitHub Releases.

Перед открытием pull request

make fmt
make clippy
make test

Если трогали документацию:

make docs-check
make docs-build

Обе языковые версии обязаны оставаться синхронными — docs-check падает на странице, которая есть только на одном языке.

Где живут обоснования решений

Решения записываются в ADR, а не обсуждаются заново на ревью. Если изменение противоречит какому-то ADR, обновлять надо именно его.

См. Architecture Decision Records.