Environment guards now exit 69 rather than 1, so a caller can tell a suite that could not start from one that ran and failed. The first toj test sweep reported "3 repositories failed" and none of the three had executed a test — two could not find go, one had no venv. That points the reader at the tests when the fault is in the environment. Only the environment guards change. A gitleaks finding, a failed test run and a vulncheck hit still exit 1, because those did run and did fail. Co-Authored-By: Claude <noreply@anthropic.com>
99 lines
4.0 KiB
Makefile
99 lines
4.0 KiB
Makefile
# desklock — one entry point for a three-component repo.
|
|
#
|
|
# firmware/ ESP-IDF application for the device. No tests, no release flow.
|
|
# gateway/ Python service on :8600. The only component with a test suite.
|
|
# sim/ a static page that mimics the device face in a browser.
|
|
#
|
|
# This lives at the root and the components have no Makefiles of their own, so
|
|
# `make test` means the same thing wherever you are standing. A per-component
|
|
# Makefile makes it mean "some of the tests" depending on your working
|
|
# directory, which is the `git -C` failure in another costume (D-27).
|
|
#
|
|
# Paths resolve here rather than in callers (D-10). Two of them bite:
|
|
#
|
|
# ESP-IDF is invisible until export.sh is sourced, so `idf.py` is
|
|
# "command not found" for anyone who forgets — the same class of failure as
|
|
# the four tool-resolution misses recorded in D-24. The firmware targets
|
|
# source it themselves.
|
|
#
|
|
# `python3` on this host is 3.8, which cannot parse the gateway's sources.
|
|
# PYTHON names 3.12 explicitly and is overridable for other machines.
|
|
|
|
PYTHON ?= python3.12
|
|
IDF_EXPORT ?= $(HOME)/esp-idf/export.sh
|
|
GATEWAY := $(CURDIR)/gateway
|
|
VENV := $(GATEWAY)/.venv
|
|
|
|
.DEFAULT_GOAL := help
|
|
|
|
.PHONY: help
|
|
help: ## Show this help
|
|
@grep -hE '^[a-z][a-z0-9_-]*:.*?## ' $(MAKEFILE_LIST) \
|
|
| awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-16s\033[0m %s\n", $$1, $$2}'
|
|
|
|
# --- the three D-27 required targets -----------------------------------------
|
|
|
|
.PHONY: test
|
|
test: test-gateway ## Run every component's tests that exist
|
|
@echo " -- firmware: no test suite (undetermined, not passing)"
|
|
@echo " -- sim: a static page, nothing to test"
|
|
|
|
.PHONY: lint
|
|
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)
|
|
cd $(GATEWAY) && $(PYTHON) -m venv .venv && .venv/bin/pip install -e ".[dev]"
|
|
|
|
.PHONY: setup-speech
|
|
setup-speech: ## Additionally install faster-whisper and piper
|
|
cd $(GATEWAY) && .venv/bin/pip install -e ".[dev,speech]"
|
|
|
|
.PHONY: run
|
|
run: ## Run the gateway on :8600 with reload
|
|
cd $(GATEWAY) && .venv/bin/uvicorn desklock_gateway.main:app --host 0.0.0.0 --port 8600 --reload
|
|
|
|
.PHONY: test-gateway
|
|
test-gateway: ## Gateway pytest suite
|
|
@cd $(GATEWAY) && .venv/bin/pytest
|
|
|
|
.PHONY: lint-gateway
|
|
lint-gateway: ## ruff check and format --check over the gateway
|
|
cd $(GATEWAY) && .venv/bin/ruff check src tests && .venv/bin/ruff format --check src tests
|
|
|
|
.PHONY: typecheck
|
|
typecheck: ## mypy over the gateway sources
|
|
cd $(GATEWAY) && .venv/bin/mypy src
|
|
|
|
# --- firmware -----------------------------------------------------------------
|
|
#
|
|
# Each target sources export.sh in its own shell. That is deliberate: make runs
|
|
# every recipe line in a fresh shell, so exporting in one target would not carry
|
|
# to the next, and a caller who sources it by hand still works because sourcing
|
|
# twice is harmless.
|
|
|
|
.PHONY: build-firmware
|
|
build-firmware: ## Build the ESP-IDF firmware (sources export.sh for you)
|
|
@test -f $(IDF_EXPORT) || { echo "FAIL — no ESP-IDF at $(IDF_EXPORT); set IDF_EXPORT=<path>/export.sh"; exit 69; }
|
|
. $(IDF_EXPORT) && cd firmware && idf.py build
|
|
|
|
.PHONY: flash
|
|
flash: ## Flash and monitor the device (PORT=/dev/ttyACM0 by default)
|
|
@test -f $(IDF_EXPORT) || { echo "FAIL — no ESP-IDF at $(IDF_EXPORT); set IDF_EXPORT=<path>/export.sh"; exit 69; }
|
|
. $(IDF_EXPORT) && cd firmware && idf.py -p $(or $(PORT),/dev/ttyACM0) flash monitor
|
|
|
|
# --- sim ----------------------------------------------------------------------
|
|
|
|
.PHONY: serve-sim
|
|
serve-sim: ## Serve the face simulator on :8601
|
|
cd sim/face && $(PYTHON) -m http.server 8601
|
|
|
|
# --- housekeeping -------------------------------------------------------------
|
|
|
|
.PHONY: clean
|
|
clean: ## Remove the gateway venv and caches
|
|
rm -rf $(VENV) $(GATEWAY)/.pytest_cache $(GATEWAY)/.ruff_cache $(GATEWAY)/.mypy_cache
|
|
find $(GATEWAY) -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|