Skip to content

Commit f1af42d

Browse files
committed
tooling: Add venv support to Makefile with MicroPython stubs.
1 parent 069c1d8 commit f1af42d

3 files changed

Lines changed: 25 additions & 14 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ __pycache__
88
node_modules/
99
CLAUDE.md
1010
.build/
11+
.venv/

Makefile

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
include env.mk
66

7+
# Venv path (override with VENV_DIR=/path for devcontainer)
8+
VENV_DIR ?= .venv
9+
10+
# Use venv Python/tools when available, fallback to system
11+
PYTHON := $(shell [ -x $(VENV_DIR)/bin/python ] && echo $(VENV_DIR)/bin/python || echo python3)
12+
713
# --- Setup ---
814

915
# npm install is re-run only when package.json changes
@@ -18,9 +24,12 @@ prepare: node_modules/.package-lock.json ## Install git hooks
1824
.PHONY: setup
1925
setup: install prepare ## Full dev environment setup
2026

27+
$(VENV_DIR)/bin/activate:
28+
python3 -m venv $(VENV_DIR)
29+
2130
.PHONY: install
22-
install: node_modules/.package-lock.json ## Install dev tools (pip + npm)
23-
python3 -m pip install -e ".[dev,test]"
31+
install: $(VENV_DIR)/bin/activate node_modules/.package-lock.json ## Install dev tools (pip + npm)
32+
$(VENV_DIR)/bin/pip install -e ".[dev,test]"
2433

2534
# --- Linting ---
2635

@@ -37,12 +46,12 @@ lint-fix: ## Auto-fix lint issues
3746
# Dynamic per-scenario targets (test-apds9960, test-hts221, etc.)
3847
# Uses 'driver' field for driver scenarios, filename stem for board scenarios.
3948
# Convention: for board scenarios, the YAML 'name' field must match the filename.
40-
SCENARIOS := $(shell python3 -c "import yaml,glob,os; [print(d.get('driver',os.path.basename(f).replace('.yaml',''))) for f in sorted(glob.glob('tests/scenarios/*.yaml')) for d in [yaml.safe_load(open(f))]]" 2>/dev/null)
41-
$(foreach s,$(SCENARIOS),$(eval .PHONY: test-$(s))$(eval test-$(s): ; python3 -m pytest tests/ -v -k "$(s)" --port $$(PORT) -s))
49+
SCENARIOS := $(shell $(PYTHON) -c "import yaml,glob,os; [print(d.get('driver',os.path.basename(f).replace('.yaml',''))) for f in sorted(glob.glob('tests/scenarios/*.yaml')) for d in [yaml.safe_load(open(f))]]" 2>/dev/null)
50+
$(foreach s,$(SCENARIOS),$(eval .PHONY: test-$(s))$(eval test-$(s): ; $(PYTHON) -m pytest tests/ -v -k "$(s)" --port $$(PORT) -s))
4251

4352
.PHONY: test-mock
4453
test-mock: ## Run mock tests (no hardware needed)
45-
python3 -m pytest tests/ -v -k mock
54+
$(PYTHON) -m pytest tests/ -v -k mock
4655

4756
.PHONY: test
4857
test: test-mock ## Run mock tests (use 'make test-all' for mock + hardware)
@@ -51,23 +60,23 @@ test: test-mock ## Run mock tests (use 'make test-all' for mock + hardware)
5160

5261
.PHONY: test-hardware
5362
test-hardware: ## Run all hardware tests (needs board on PORT)
54-
python3 -m pytest tests/ -v --port $(PORT) -s -k hardware
63+
$(PYTHON) -m pytest tests/ -v --port $(PORT) -s -k hardware
5564

5665
.PHONY: test-board
5766
test-board: ## Run board tests only (buttons, LEDs, buzzer, screen)
58-
python3 -m pytest tests/ -v --port $(PORT) -s -k "board_ and hardware"
67+
$(PYTHON) -m pytest tests/ -v --port $(PORT) -s -k "board_ and hardware"
5968

6069
.PHONY: test-sensors
6170
test-sensors: ## Run sensor driver hardware tests (I2C devices)
62-
python3 -m pytest tests/ -v --port $(PORT) -s -k "hardware and not board_"
71+
$(PYTHON) -m pytest tests/ -v --port $(PORT) -s -k "hardware and not board_"
6372

6473
.PHONY: test-all
6574
test-all: ## Run all tests (mock + hardware)
66-
python3 -m pytest tests/ -v --port $(PORT) -s
75+
$(PYTHON) -m pytest tests/ -v --port $(PORT) -s
6776

6877
.PHONY: test-examples
6978
test-examples: ## Validate all example files (syntax + imports)
70-
python3 -m pytest tests/test_examples.py -v
79+
$(PYTHON) -m pytest tests/test_examples.py -v
7180

7281
# --- CI ---
7382

@@ -179,7 +188,7 @@ bump: ## Create a version tag (PART=patch|minor|major, default: patch)
179188
fi; \
180189
echo "$$LAST → $$NEXT"; \
181190
VERSION=$${NEXT#v}; \
182-
python3 -c "import re, pathlib; p=pathlib.Path('pyproject.toml'); p.write_text(re.sub(r'^version = \".*\"', 'version = \"$$VERSION\"', p.read_text(), count=1, flags=re.MULTILINE))"; \
191+
$(PYTHON) -c "import re, pathlib; p=pathlib.Path('pyproject.toml'); p.write_text(re.sub(r'^version = \".*\"', 'version = \"$$VERSION\"', p.read_text(), count=1, flags=re.MULTILINE))"; \
183192
git add pyproject.toml; \
184193
git commit -m "chore: Bump version to $$NEXT."; \
185194
git tag -a "$$NEXT" -m "Release $$NEXT"; \
@@ -194,10 +203,11 @@ clean: ## Remove build artifacts and caches
194203
find . -type d -name .pytest_cache -exec rm -rf {} + 2>/dev/null || true
195204
find . -type d -name .ruff_cache -exec rm -rf {} + 2>/dev/null || true
196205
find . -type d -name .mypy_cache -exec rm -rf {} + 2>/dev/null || true
206+
find . -type d -name '*.egg-info' -exec rm -rf {} + 2>/dev/null || true
197207

198208
.PHONY: deepclean
199-
deepclean: clean ## Remove everything including node_modules and firmware
200-
rm -rf node_modules
209+
deepclean: clean ## Remove everything including node_modules, venv and firmware
210+
rm -rf node_modules $(VENV_DIR)
201211
@if [ -d "$(BUILD_DIR)" ]; then rm -rf "$(BUILD_DIR)"; fi
202212

203213
.PHONY: help

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ license = {text = "GPL-3.0-or-later"}
1010
requires-python = ">=3.7"
1111

1212
[project.optional-dependencies]
13-
dev = ["ruff==0.11.6"]
13+
dev = ["ruff==0.11.6", "micropython-stm32-stubs>=1.24"]
1414
test = ["pytest==7.4.0", "pyyaml==6.0.2", "mpremote>=1.0"]
1515

1616
[tool.setuptools]

0 commit comments

Comments
 (0)