ci(hooks-specific): 👷 Add validation checks in enforce-structure.sh hook to enforce project structure rules
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
09ff3012dd
commit
ff84b11125
1 changed files with 18 additions and 10 deletions
|
|
@ -17,7 +17,7 @@
|
|||
# │ ├── scenes/ # .tscn + .gd (main, menus, world_map, tests)
|
||||
# │ └── tests/ # GUT unit + integration tests
|
||||
# ├── games/
|
||||
# │ └── age-of-four/
|
||||
# │ └── age-of-dwarves/
|
||||
# │ ├── data/ # ALL game JSON (terrain/, units/, spells/, etc.)
|
||||
# │ ├── assets/ # sprites, icons
|
||||
# │ ├── docs/ # game design docs
|
||||
|
|
@ -25,8 +25,8 @@
|
|||
# │ └── vocabulary.json # engine term -> display string
|
||||
# ├── guide/
|
||||
# │ ├── engine/ # @magic-civ/guide-engine (shared React components)
|
||||
# │ ├── age-of-four/ # web app (React + Vite)
|
||||
# │ └── themes/ -> ../../games/age-of-four # SYMLINK (do not write here)
|
||||
# │ ├── age-of-dwarves/ # web app (React + Vite)
|
||||
# │ └── themes/ -> ../../games/age-of-dwarves # SYMLINK (do not write here)
|
||||
# ├── packages/
|
||||
# │ └── engine-ts/ # @magic-civ/engine-ts (auto-generated from GDScript)
|
||||
# ├── tools/
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
# 2. Files must be in allowed top-level directories
|
||||
# 3. No .messy/ paths in runtime code (planning docs exempt)
|
||||
# 4. GDScript files must be <=500 lines
|
||||
# 5. Game data JSON must live in games/age-of-four/data/
|
||||
# 5. Game data JSON must live in games/age-of-dwarves/data/
|
||||
# 6. guide/themes/ is read-only symlink territory
|
||||
#
|
||||
set -euo pipefail
|
||||
|
|
@ -66,7 +66,7 @@ REL="${FILE#$REPO_ROOT/}"
|
|||
# ── Rule 1: No symlinks ──────────────────────────────────────────────────────
|
||||
# Block creating files inside guide/themes/ (the symlink indirection)
|
||||
if [[ "$REL" == guide/themes/* ]]; then
|
||||
echo '{"decision":"block","reason":"STRUCTURE VIOLATION: guide/themes/ is a symlink indirection. Write data to games/age-of-four/data/ directly, and guide code to guide/."}'
|
||||
echo '{"decision":"block","reason":"STRUCTURE VIOLATION: guide/themes/ is a symlink indirection. Write data to games/age-of-dwarves/data/ directly, and guide code to guide/."}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
|
@ -112,18 +112,18 @@ if [[ "$REL" == *.gd ]]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# ── Rule 5: Data JSON only in games/age-of-four/data/ ────────────────────────
|
||||
# ── Rule 5: Data JSON only in games/age-of-dwarves/data/ ────────────────────────
|
||||
if [[ "$REL" == *.json ]]; then
|
||||
# Allow package.json, tsconfig.json, vite configs, etc.
|
||||
BASENAME=$(basename "$REL")
|
||||
case "$BASENAME" in
|
||||
package.json|tsconfig.json|tsconfig.*.json|vitest.config.*|.gutconfig.json) ;;
|
||||
*)
|
||||
# If it's game data (not config), it must be in games/age-of-four/data/
|
||||
if [[ "$REL" != games/age-of-four/data/* && "$REL" != games/age-of-four/game.json && "$REL" != games/age-of-four/vocabulary.json && "$REL" != .claude/* && "$REL" != .project/* ]]; then
|
||||
# If it's game data (not config), it must be in games/age-of-dwarves/data/
|
||||
if [[ "$REL" != games/age-of-dwarves/data/* && "$REL" != games/age-of-dwarves/game.json && "$REL" != games/age-of-dwarves/vocabulary.json && "$REL" != .claude/* && "$REL" != .project/* ]]; then
|
||||
# Check if it looks like game data (has "id" field or is in a data-like path)
|
||||
if echo "$CONTENT" | jq -e '.[0].id // .id // .races // .terrain // empty' >/dev/null 2>&1; then
|
||||
echo "{\"decision\":\"block\",\"reason\":\"STRUCTURE VIOLATION: Game data JSON '$REL' must live in games/age-of-four/data/. The guide reads from there via symlink — never duplicate data.\"}"
|
||||
echo "{\"decision\":\"block\",\"reason\":\"STRUCTURE VIOLATION: Game data JSON '$REL' must live in games/age-of-dwarves/data/. The guide reads from there via symlink — never duplicate data.\"}"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
|
@ -134,7 +134,15 @@ fi
|
|||
# ── Rule 6: No guide/themes/ directory (symlink violation) ───────────────────
|
||||
# Already caught by Rule 1, but explicit for clarity
|
||||
if [[ "$REL" == guide/themes/* ]]; then
|
||||
echo '{"decision":"block","reason":"STRUCTURE VIOLATION: guide/themes/ must not contain files. It should be a symlink to games/age-of-four/. Write data to games/age-of-four/data/ instead."}'
|
||||
echo '{"decision":"block","reason":"STRUCTURE VIOLATION: guide/themes/ must not contain files. It should be a symlink to games/age-of-dwarves/. Write data to games/age-of-dwarves/data/ instead."}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ── Rule 7: Never edit *.generated.ts files ──────────────────────────────────
|
||||
# These are auto-generated by the transpiler from GDScript sources.
|
||||
# Fix the GDScript source + re-run transpiler instead.
|
||||
if [[ "$REL" == *.generated.ts ]]; then
|
||||
echo "{\"decision\":\"block\",\"reason\":\"GENERATED FILE: '$REL' is auto-generated by the transpiler. Edit the GDScript source or transpiler assembly instead, then run: uv run tools/transpile-engine/transpile.py\"}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue