Consolidates all connector scripts under tooling/ per project structure conventions. Symlink at db/connectors → tooling/db/ preserves backwards compatibility (remove after Sprint 22). Updated references in CLAUDE.md, Makefile, DEVOPS.md, all skill files, agent files, rules, schema comments, and Sprint 21 briefings. Python scripts updated with correct SCHEMA_PATH (now relative to WORKTREE_ROOT/db/schema.sql). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
332 lines
12 KiB
Makefile
332 lines
12 KiB
Makefile
GODOT := $(shell command -v godot4 2>/dev/null || command -v godot 2>/dev/null)
|
|
|
|
.PHONY: help setup build check-protocol client server game stop test lint ci ci-client ci-server clean \
|
|
decisions-sync decisions-coverage decisions-active decisions-orphan \
|
|
db-backup db-install validate-content content-ron check-fact-ids setup-hooks \
|
|
pre-pr pre-pr-lint pre-pr-build pre-pr-test pre-pr-validate pre-pr-fixtures \
|
|
pre-pr-server pre-pr-client pre-pr-content \
|
|
fixtures-client golden-diff golden-update \
|
|
checklist-validate checklist-generate \
|
|
perf-baseline debug-schedule \
|
|
test-ipc-fixtures test-ipc-protocol test-ipc-integration test-ipc-benchmark
|
|
|
|
# --- Configuration ---
|
|
|
|
GODOT_VERSION ?= 4.6
|
|
|
|
# Default
|
|
help:
|
|
@echo "The Settled Reach — Development Commands"
|
|
@echo ""
|
|
@echo " make setup Install dev dependencies (Rust, Godot, tooling)"
|
|
@echo " make build Build client and server"
|
|
@echo " make game Build and run the full game (server + client)"
|
|
@echo " make stop Stop any running server instance"
|
|
@echo " make client Run the Godot client (test mode)"
|
|
@echo " make server Run the Rust simulation server"
|
|
@echo " make test Run all tests"
|
|
@echo " make test-ipc-fixtures Layer 1: IPC serialization fixtures"
|
|
@echo " make test-ipc-protocol Layer 2: mock IPC protocol tests"
|
|
@echo " make test-ipc-integration Layer 3: real subprocess round-trip"
|
|
@echo " make test-ipc-benchmark IPC latency benchmark (blocked: #555/#556)"
|
|
@echo " make lint Run all linters"
|
|
@echo " make ci Run full CI pipeline locally"
|
|
@echo " make ci-client Run client CI checks"
|
|
@echo " make ci-server Run server CI checks"
|
|
@echo " make check-protocol Verify server/client protocol versions match"
|
|
@echo " make clean Remove build artifacts and caches"
|
|
@echo ""
|
|
@echo " make db-backup Backup shared database to git (main only)"
|
|
@echo " make db-install Restore shared database from backup"
|
|
@echo ""
|
|
@echo " make decisions-sync Sync decisions/*.md into SQLite"
|
|
@echo " make decisions-coverage Decision-to-ticket coverage by domain"
|
|
@echo " make decisions-active List active decisions"
|
|
@echo " make decisions-orphan Decisions without implementing tickets"
|
|
@echo " make validate-content Validate content YAML against schemas"
|
|
@echo " make check-fact-ids Check fact_id references against knowledge catalogs"
|
|
@echo " make content-ron Convert content YAML to RON (build-time)"
|
|
@echo " make fixtures-client Generate GDScript->Rust cross-encoder fixtures (#475)"
|
|
@echo " make golden-diff Show diff if golden file output has changed"
|
|
@echo " make golden-update Regenerate golden file and stage for commit"
|
|
@echo " make checklist-validate Validate checklist YAML against schema"
|
|
@echo " make checklist-generate Validate checklists + print condition summary"
|
|
@echo " make perf-baseline Run performance benchmarks and save baseline"
|
|
@echo ""
|
|
@echo " make pre-pr Run all pre-PR checks (lint, build, test, validate, fixtures)"
|
|
@echo " make pre-pr-server Server-scoped pre-PR (lint, build, test, fixtures)"
|
|
@echo " make pre-pr-client Client-scoped pre-PR (lint, build, test)"
|
|
@echo " make pre-pr-content Content-scoped pre-PR (schema + cross-ref validation)"
|
|
@echo ""
|
|
@echo " make setup-hooks Install pre-commit hooks (included in setup)"
|
|
@echo " make debug-schedule Print bevy_ecs schedule graph (diff for PR artifacts)"
|
|
@echo ""
|
|
@echo " GODOT_VERSION=4.6 make setup Override Godot version"
|
|
|
|
# --- Setup ---
|
|
|
|
setup: setup-rust setup-godot setup-tooling setup-hooks decisions-sync
|
|
@echo "Dev environment ready."
|
|
|
|
setup-rust:
|
|
@tooling/install-rust
|
|
|
|
setup-godot:
|
|
@GODOT_VERSION=$(GODOT_VERSION) tooling/install-godot
|
|
|
|
setup-tooling:
|
|
@echo "Checking tooling dependencies..."
|
|
@command -v python3 >/dev/null 2>&1 || { echo "Install Python 3"; exit 1; }
|
|
@command -v curl >/dev/null 2>&1 || { echo "Install curl (required for Godot download)"; exit 1; }
|
|
@command -v unzip >/dev/null 2>&1 || { echo "Install unzip (required for Godot download)"; exit 1; }
|
|
@python3 -c "import yaml" 2>/dev/null || { echo "Install PyYAML: pip install pyyaml"; exit 1; }
|
|
@python3 -c "import jsonschema" 2>/dev/null || { echo "Install jsonschema: pip install jsonschema"; exit 1; }
|
|
|
|
setup-hooks:
|
|
@git config core.hooksPath .config/hooks
|
|
@echo "Git hooks path set to .config/hooks"
|
|
|
|
# --- Build ---
|
|
|
|
check-protocol:
|
|
@SERVER_V=$$(grep 'pub const PROTOCOL_VERSION' server/src/bridge/types.rs | sed 's/.*= *//;s/[^0-9]//g'); \
|
|
CLIENT_V=$$(grep 'const PROTOCOL_VERSION' client/scripts/protocol/protocol.gd | sed 's/.*= *//;s/[^0-9]//g'); \
|
|
if [ "$$SERVER_V" != "$$CLIENT_V" ]; then \
|
|
echo "ERROR: Protocol version mismatch — server=$$SERVER_V, client=$$CLIENT_V"; \
|
|
echo " Fix: update client/scripts/protocol/protocol.gd to match server/src/bridge/types.rs"; \
|
|
exit 1; \
|
|
fi
|
|
|
|
build: check-protocol build-server build-client
|
|
|
|
build-server:
|
|
cd server && cargo build
|
|
|
|
build-client:
|
|
@test -n "$(GODOT)" || { echo "Godot not found. Run 'make setup' first."; exit 1; }
|
|
$(GODOT) --headless --path client --import --quit
|
|
|
|
# --- Run ---
|
|
|
|
server:
|
|
cd server && cargo run --bin settled-reach-server
|
|
|
|
client:
|
|
@test -n "$(GODOT)" || { echo "Godot not found. Run 'make setup' first."; exit 1; }
|
|
$(GODOT) --path client
|
|
|
|
game: stop build
|
|
@test -n "$(GODOT)" || { echo "Godot not found. Run 'make setup' first."; exit 1; }
|
|
@echo "Starting server..."
|
|
@cd server && cargo run --bin settled-reach-server &
|
|
@sleep 2
|
|
@echo "Starting client..."
|
|
@SR_LIVE=1 $(GODOT) --path client
|
|
@$(MAKE) stop
|
|
|
|
stop:
|
|
@lsof -ti :9876 | xargs -r kill 2>/dev/null || true
|
|
@echo "Stopped any running server on port 9876"
|
|
|
|
# --- Test ---
|
|
|
|
test: test-server test-client
|
|
|
|
test-server:
|
|
tests/run-rust
|
|
|
|
fixtures:
|
|
cd server && cargo test --test gen_fixtures -- --ignored
|
|
|
|
fixtures-client:
|
|
@test -n "$(GODOT)" || { echo "Godot not found. Run 'make setup' first."; exit 1; }
|
|
@echo "Generating GDScript fixtures for Rust decoder..."
|
|
$(GODOT) --headless --path client -s res://tests/gen_client_fixtures.gd
|
|
@echo "Verifying Rust can decode GDScript fixtures..."
|
|
cd server && cargo test --test serialization gdscript_generated_fixtures
|
|
@echo "--- Fixtures-client: PASS ---"
|
|
|
|
golden-diff:
|
|
@echo "Regenerating golden output for comparison..."
|
|
@mkdir -p .cache/golden
|
|
@cp server/tests/golden/proof_room_tick_10.json .cache/golden/before.json
|
|
@cd server && UPDATE_GOLDEN=1 cargo test --test golden_suite -- proof_room_tick_10_matches_golden; \
|
|
rc=$$?; \
|
|
cp ../server/tests/golden/proof_room_tick_10.json ../.cache/golden/after.json 2>/dev/null; \
|
|
cp ../.cache/golden/before.json ../server/tests/golden/proof_room_tick_10.json; \
|
|
if [ $$rc -ne 0 ]; then echo "Cargo test failed (golden file restored)."; exit $$rc; fi
|
|
@if diff -q .cache/golden/before.json .cache/golden/after.json >/dev/null 2>&1; then \
|
|
echo "--- Golden file: UP TO DATE ---"; \
|
|
else \
|
|
echo "--- Golden file has CHANGED ---"; \
|
|
echo ""; \
|
|
diff --color -u .cache/golden/before.json .cache/golden/after.json || true; \
|
|
echo ""; \
|
|
echo "Run 'make golden-update' to accept changes."; \
|
|
exit 1; \
|
|
fi
|
|
|
|
golden-update:
|
|
@echo "Regenerating golden file..."
|
|
@cd server && UPDATE_GOLDEN=1 cargo test --test golden_suite -- proof_room_tick_10_matches_golden
|
|
@git add server/tests/golden/
|
|
@echo "--- Golden file updated and staged ---"
|
|
@echo "Review with: git diff --cached -- server/tests/golden/"
|
|
|
|
test-client:
|
|
tests/run-godot
|
|
|
|
test-ipc-fixtures:
|
|
tests/run-ipc-fixtures
|
|
|
|
test-ipc-protocol:
|
|
tests/run-ipc-protocol
|
|
|
|
test-ipc-integration:
|
|
tests/run-ipc-integration
|
|
|
|
test-ipc-benchmark:
|
|
tests/run-ipc-benchmark
|
|
|
|
# --- Lint ---
|
|
|
|
lint: lint-server lint-client
|
|
|
|
lint-server:
|
|
cd server && cargo clippy -- -D warnings
|
|
cd server && cargo fmt --check
|
|
|
|
lint-client:
|
|
@test -n "$(GODOT)" || { echo "Godot not found. Run 'make setup' first."; exit 1; }
|
|
@echo "Checking GDScript for errors..."
|
|
@$(GODOT) --headless --path client --quit 2>&1 | grep -i "SCRIPT ERROR" && { echo "GDScript errors found"; exit 1; } || echo "No script errors found"
|
|
|
|
# --- Pre-PR verification ---
|
|
|
|
pre-pr: pre-pr-lint pre-pr-build pre-pr-test pre-pr-validate pre-pr-fixtures
|
|
@echo ""
|
|
@echo "=== PRE-PR: ALL CHECKS PASSED ==="
|
|
@echo "Safe to create PR."
|
|
|
|
pre-pr-lint: lint-server lint-client
|
|
@echo "--- Lint: PASS ---"
|
|
|
|
pre-pr-build: build-server build-client
|
|
@echo "--- Build: PASS ---"
|
|
|
|
pre-pr-test: test-server test-client
|
|
@echo "--- Tests: PASS ---"
|
|
|
|
pre-pr-validate: validate-content check-fact-ids
|
|
@echo "--- Content validation: PASS ---"
|
|
|
|
pre-pr-fixtures:
|
|
@echo "Checking Rust->GDScript fixture staleness..."
|
|
@cd server && cargo test --test gen_fixtures -- --ignored
|
|
@if git diff --quiet client/tests/fixtures/; then \
|
|
echo "--- Rust fixtures: UP TO DATE ---"; \
|
|
else \
|
|
echo ""; \
|
|
echo "--- RUST FIXTURES STALE ---"; \
|
|
echo " Protocol changed but fixtures not regenerated."; \
|
|
echo " Stale fixtures make all client tests FALSE POSITIVES."; \
|
|
echo ""; \
|
|
echo " Changed files:"; \
|
|
git diff --stat client/tests/fixtures/; \
|
|
echo ""; \
|
|
echo " Fix: commit the updated fixtures with your protocol change."; \
|
|
exit 1; \
|
|
fi
|
|
@echo "Checking GDScript->Rust fixture staleness..."
|
|
@$(MAKE) fixtures-client
|
|
@if git diff --quiet server/tests/fixtures/gdscript/; then \
|
|
echo "--- GDScript fixtures: UP TO DATE ---"; \
|
|
else \
|
|
echo ""; \
|
|
echo "--- GDSCRIPT FIXTURES STALE ---"; \
|
|
echo " Protocol changed but GDScript fixtures not regenerated."; \
|
|
echo " Stale fixtures make cross-encoder tests FALSE POSITIVES."; \
|
|
echo ""; \
|
|
echo " Changed files:"; \
|
|
git diff --stat server/tests/fixtures/gdscript/; \
|
|
echo ""; \
|
|
echo " Fix: commit the updated fixtures with your protocol change."; \
|
|
exit 1; \
|
|
fi
|
|
|
|
# Branch-specific variants (faster, scope-appropriate)
|
|
|
|
pre-pr-server: lint-server build-server test-server pre-pr-fixtures
|
|
@echo "=== Server pre-PR: PASSED ==="
|
|
|
|
pre-pr-client: lint-client build-client test-client
|
|
@echo "=== Client pre-PR: PASSED ==="
|
|
|
|
pre-pr-content: validate-content check-fact-ids checklist-validate
|
|
@echo "=== Content pre-PR: PASSED ==="
|
|
|
|
# --- CI (run locally) ---
|
|
|
|
ci: ci-server ci-client
|
|
|
|
ci-server: lint-server build-server test-server
|
|
|
|
ci-client: lint-client build-client test-client
|
|
|
|
# --- Database ---
|
|
|
|
db-backup:
|
|
@tooling/db-backup
|
|
|
|
db-install:
|
|
@tooling/db-install
|
|
|
|
# --- Decisions ---
|
|
|
|
decisions-sync:
|
|
@tooling/db/decisions-sync
|
|
|
|
decisions-coverage:
|
|
@tooling/db/sqlite-query "SELECT d.domain, COUNT(DISTINCT d.id) as decisions, COUNT(DISTINCT t.decision_ref) as with_tickets FROM decisions d LEFT JOIN tickets t ON d.id = t.decision_ref WHERE d.status='active' AND d.type='confirmed' GROUP BY d.domain"
|
|
|
|
decisions-active:
|
|
@tooling/db/sqlite-query "SELECT id, domain, title FROM decisions WHERE status='active' AND type='confirmed' ORDER BY domain, id"
|
|
|
|
decisions-orphan:
|
|
@tooling/db/sqlite-query "SELECT id, title FROM decisions WHERE type='confirmed' AND status='active' AND id NOT IN (SELECT DISTINCT decision_ref FROM tickets WHERE decision_ref IS NOT NULL)"
|
|
|
|
# --- Content Validation ---
|
|
|
|
validate-content:
|
|
@tooling/validate-content
|
|
|
|
check-fact-ids:
|
|
@tooling/check-fact-ids
|
|
|
|
checklist-validate:
|
|
@tooling/validate-checklist --check
|
|
|
|
checklist-generate:
|
|
@tooling/validate-checklist
|
|
|
|
perf-baseline:
|
|
@tooling/perf-baseline
|
|
|
|
# --- Schedule debug (#346) ---
|
|
|
|
debug-schedule:
|
|
@echo "Dumping bevy_ecs schedule graph..."
|
|
@cd server && cargo run --bin settled-reach-server -- --dump-schedule
|
|
|
|
content-ron:
|
|
cd tooling/content-converter && cargo build --release
|
|
tooling/content-converter/target/release/content-converter --input content --output content-ron --verbose
|
|
|
|
# --- Clean ---
|
|
|
|
clean:
|
|
cd server && cargo clean || true
|
|
rm -rf .cache/*
|
|
rm -rf client/.godot/* client/reports
|
|
@echo "Clean complete."
|