add make setup and network-free deps.check guard

mix deps.get contacts hex.pm even when everything is already installed
(the advisory check), so the everyday loops failed in offline/sandboxed
environments; and the root deps target only installed app's deps, never
blogex's.

make setup (root) installs Hex deps for both apps plus the app's JS
packages, once per clone, explicitly. check, test and test.coverage in
both apps now depend on a local deps.check guard instead: every package
pinned in mix.lock must exist in deps/, else fail loudly pointing at
make setup. AGENTS.md documents the new target.
This commit is contained in:
Firehose Bot
2026-10-29 17:44:16 +00:00
parent 7215cd6db0
commit 97fc024a38
4 changed files with 62 additions and 17 deletions
+5
View File
@@ -70,6 +70,11 @@ This is a Phoenix Liveview monorepo, the blogging library is in blogex, the appl
Main make targets:
- `make setup` - one-time clone setup (and after any mix.exs gains a dep):
fetches Hex deps for both apps and the app's JS packages. Needs network -
run it yourself; agent sandboxes refuse installs. check/test/verify never
touch the network: they run a local `deps.check` guard that fails with a
pointer here when deps are missing.
- `make check` - cheap static gate for both apps (no DB): app `credo --strict` +
format **check** (`mix format --check-formatted`), blogex compile (warnings
fatal) + format **check**, then `scripts/check-pins.sh`. It never rewrites
+13 -4
View File
@@ -2,7 +2,7 @@
MISE_BIN ?= mise
.PHONY: check precommit verify hooks deps compile test test-elisp format
.PHONY: check precommit verify hooks deps setup compile test test-elisp format
# Cheap static gate over both apps, cheapest first. No database, no coverage:
# this is the loop you run freely while working and before every commit.
@@ -47,9 +47,18 @@ hooks:
echo "installed $$hooks_dir/$$name -> $$hook"; \
done
# Sync dependencies
deps:
@make -C app deps
# One-time setup for this clone (and after any mix.exs gains a dependency):
# fetches Hex deps for both apps and the app's JS packages. Needs network, and
# is deliberately NOT wired into check/test/verify: `mix deps.get` contacts
# hex.pm even when everything is already installed (the advisory check), which
# fails offline/sandboxed. The everyday loops run the per-app `deps.check`
# guard instead and point here when deps are missing.
setup:
@$(MAKE) -C app MISE_BIN=$(MISE_BIN) deps
@$(MAKE) -C blogex MISE_BIN=$(MISE_BIN) deps
# Kept for muscle memory; `setup` is the canonical entry point.
deps: setup
# Compile the project
compile:
+22 -7
View File
@@ -3,12 +3,13 @@
MISE_BIN ?= mise
MISE_EXEC = $(MISE_BIN) exec --
.PHONY: check precommit deps assets compile test test.coverage sobelow coverage crap format format.check credo verify
.PHONY: check precommit deps deps.check assets compile test test.coverage sobelow coverage crap format format.check credo verify
# Run all static analysis checks (no database required). `format.check` only
# reports: a gate that rewrites the files it judges can never fail. Fix
# formatting with `make format`.
check: credo format.check
# Run all static analysis checks (no database, no network required). The
# deps.check guard fails loudly with a pointer at `make setup` when Hex deps
# are missing. `format.check` only reports: a gate that rewrites the files it
# judges can never fail. Fix formatting with `make format`.
check: deps.check credo format.check
# Precommit target for CI/pre-commit hooks
precommit: check compile
@@ -27,19 +28,33 @@ assets:
deps: assets
$(MISE_EXEC) mix deps.get
# Local, network-free guard: every package pinned in mix.lock must be present
# in deps/. check, test and test.coverage depend on this instead of `deps`, so
# the everyday loops never touch the network: `mix deps.get` contacts hex.pm
# even when everything is already installed (the advisory check), which fails
# in offline/sandboxed environments. Fetching is `make setup`'s explicit job,
# run from the repo root.
deps.check:
@test -f mix.lock || { echo "deps.check: no mix.lock - run 'make setup' at the repo root" >&2; exit 1; }
@missing=""; \
for dep in $$(sed -n 's/^[[:space:]]*"\([^"]*\)".*/\1/p' mix.lock); do \
[ -d "deps/$$dep" ] || missing="$$missing $$dep"; \
done; \
test -z "$$missing" || { echo "deps.check: missing:$$missing - run 'make setup' at the repo root" >&2; exit 1; }
# Compile the project
compile:
$(MISE_EXEC) mix compile --warnings-as-errors
# Run tests (requires PostgreSQL running on localhost:5432)
# Note: If you don't have PostgreSQL, you can skip tests with `make check`
test: deps compile
test: deps.check compile
$(MISE_EXEC) mix test
# Run the suite once with coverage exported, so the coverage floor check (and,
# later, CRAP) reads the export instead of running the suite a second time.
# Stale exports are removed first: the floor must never report an older run.
test.coverage: deps compile
test.coverage: deps.check compile
rm -f cover/*.coverdata
$(MISE_EXEC) mix test --cover --export-coverage default
+22 -6
View File
@@ -3,17 +3,19 @@
MISE_BIN ?= mise
MISE_EXEC = $(MISE_BIN) exec --
.PHONY: check precommit deps compile test test.coverage coverage crap format format.check verify
.PHONY: check precommit deps deps.check compile test test.coverage coverage crap format format.check verify
# Cheap static gate for this library (no database, no coverage). Runs from the
# root `make check`, which loops app then blogex. `format.check` only reports:
# Cheap static gate for this library (no database, no network, no coverage).
# The deps.check guard fails loudly with a pointer at `make setup` when Hex
# deps are missing. Runs from the root `make check`, which loops app then
# blogex. `format.check` only reports:
# a gate that rewrites the files it judges can never fail. Fix formatting with
# `make format`.
#
# Sensor slot: add `credo` once the "credo strict, tuned config (both apps)"
# yak lands blogex's credo dep + .credo.exs. Do not list it before then — a
# gate that claims a check it did not run is worse than no gate.
check: compile format.check
check: deps.check compile format.check
# Per-app precommit loop: same target name and alias shape as app/, so both
# apps share one habit (compile --warning-as-errors, format, test).
@@ -24,18 +26,32 @@ precommit:
deps:
$(MISE_EXEC) mix deps.get
# Local, network-free guard: every package pinned in mix.lock must be present
# in deps/. check, test and test.coverage depend on this instead of `deps`, so
# the everyday loops never touch the network: `mix deps.get` contacts hex.pm
# even when everything is already installed (the advisory check), which fails
# in offline/sandboxed environments. Fetching is `make setup`'s explicit job,
# run from the repo root.
deps.check:
@test -f mix.lock || { echo "deps.check: no mix.lock - run 'make setup' at the repo root" >&2; exit 1; }
@missing=""; \
for dep in $$(sed -n 's/^[[:space:]]*"\([^"]*\)".*/\1/p' mix.lock); do \
[ -d "deps/$$dep" ] || missing="$$missing $$dep"; \
done; \
test -z "$$missing" || { echo "deps.check: missing:$$missing - run 'make setup' at the repo root" >&2; exit 1; }
# Compile the project (warnings are fatal)
compile:
$(MISE_EXEC) mix compile --warnings-as-errors
# Run the test suite
test: deps
test: deps.check
$(MISE_EXEC) mix test
# Run the suite once with coverage exported, so the coverage floor check (and,
# later, CRAP) reads the export instead of running the suite a second time.
# Stale exports are removed first: the floor must never report an older run.
test.coverage: deps
test.coverage: deps.check
rm -f cover/*.coverdata
$(MISE_EXEC) mix test --cover --export-coverage default