From 78d9b276eeadd596fef45f2b4fcffa106138e333 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Mon, 17 Aug 2026 12:04:12 +0200 Subject: [PATCH] build(make): prove make setup actually works before exiting 0 (T-47) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pip install exiting 0 is not evidence the gateway environment is usable (D-24) — a resolved-but-broken dependency or a stale venv from another Python both look identical to a clean install at the point setup exits. End the target with a cheap positive check instead: collect the test suite (imports every src module each test pulls in) and confirm ruff and mypy resolve inside the venv, the only place either binary exists. Also states explicitly, in a comment, that setup covers the gateway half only — the firmware half needs `source ~/esp-idf/export.sh` in every shell, which a Makefile recipe cannot leave sourced in the caller's shell, so build-firmware sources it itself instead. --- CHANGELOG.md | 3 +++ Makefile | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 219e57a..29f68d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ until the first tagged release. removed. `make test` means the same thing from any directory. - Firmware targets source `~/esp-idf/export.sh` themselves, so `idf.py` resolves without having to remember. Override the location with `IDF_EXPORT=`. +- `make setup` now proves the gateway environment actually works instead of trusting a + clean `pip install` exit code: it collects the test suite and checks `ruff`/`mypy` + resolve in the venv, and fails the target if any of that is broken (T-47). ## [0.2.2] — 2026-07-19 diff --git a/Makefile b/Makefile index 09a326a..34b25b4 100644 --- a/Makefile +++ b/Makefile @@ -44,8 +44,28 @@ lint: lint-gateway ## Lint every component that has a linter # --- gateway ------------------------------------------------------------------ .PHONY: setup -setup: ## Create the gateway venv and install dev deps (no ML models) +setup: ## Gateway venv + dev deps + prove it works (firmware needs export.sh — see below) cd $(GATEWAY) && $(PYTHON) -m venv .venv && .venv/bin/pip install -e ".[dev]" + @# This covers the gateway half only, deliberately. The firmware half needs + @# `source ~/esp-idf/export.sh` in every shell (see the firmware gotchas + @# above); a Makefile recipe runs in its own subshell, so it cannot leave + @# that sourced in the caller's shell. A `setup` that appeared to prepare + @# firmware and silently left `idf.py` unresolved would be worse than one + @# that says plainly it does not touch that half — hence `build-firmware` + @# sources export.sh itself, per target, instead. + @# + @# Exit 0 from `pip install` is not evidence (D-24) — pip reports success + @# even when the result is unusable (e.g. a dependency that resolved but + @# doesn't actually import, or a stale .venv left over from a different + @# Python). Prove the environment works instead of trusting the install + @# step: `--collect-only` imports every test module and therefore every + @# src module each one pulls in (T-47). It runs zero tests, so it stays + @# cheap, and it also confirms ruff/mypy landed in .venv/bin — the venv + @# is the only place either binary exists (see gateway gotchas above); + @# `--version` is enough to prove each resolves and runs. + cd $(GATEWAY) && .venv/bin/python -m pytest tests/ --collect-only -q + cd $(GATEWAY) && .venv/bin/ruff --version >/dev/null + cd $(GATEWAY) && .venv/bin/mypy --version >/dev/null .PHONY: setup-speech setup-speech: ## Additionally install faster-whisper and piper