mirror of
https://github.com/Heretek-AI/godot-opencode.git
synced 2026-11-07 17:17:14 -10:00
107 lines
3.0 KiB
Bash
Executable File
107 lines
3.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Pre-commit validation hook for godot-opencode (Phase 3.5).
|
|
# - Validates staged .json tables parse (blocks on bad JSON).
|
|
# - GDScript quick check: conflict markers + obvious type-consistency slips.
|
|
# - Optionally blocks on test failure (--run-tests or VALIDATE_COMMIT_RUN_TESTS=1).
|
|
# Gracefully degrades when optional tools (python3/bun/godot) are missing.
|
|
set -euo pipefail
|
|
|
|
RUN_TESTS=0
|
|
if [[ "${1:-}" == "--run-tests" ]]; then
|
|
RUN_TESTS=1
|
|
fi
|
|
if [[ "${VALIDATE_COMMIT_RUN_TESTS:-}" == "1" ]]; then
|
|
RUN_TESTS=1
|
|
fi
|
|
|
|
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
cd "$ROOT"
|
|
|
|
STAGED="$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null || true)"
|
|
if [[ -z "$STAGED" ]]; then
|
|
echo "validate-commit: no staged changes, ok"
|
|
exit 0
|
|
fi
|
|
|
|
fail() {
|
|
echo "validate-commit: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
json_ok() {
|
|
local file="$1"
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
python3 -c 'import json,sys; json.load(open(sys.argv[1]))' "$file" 2>/dev/null
|
|
return $?
|
|
fi
|
|
if command -v bun >/dev/null 2>&1; then
|
|
bun -e 'const f=Bun.file(process.argv[2]); JSON.parse(await f.text())' -- "$file" 2>/dev/null
|
|
return $?
|
|
fi
|
|
if command -v node >/dev/null 2>&1; then
|
|
node -e 'require("fs"); JSON.parse(require("fs").readFileSync(process.argv[1],"utf8"))' "$file" 2>/dev/null
|
|
return $?
|
|
fi
|
|
echo "validate-commit: warning: no JSON parser available, skipping $file" >&2
|
|
return 0
|
|
}
|
|
|
|
JSON_FAILED=0
|
|
while IFS= read -r file; do
|
|
[[ -z "$file" ]] && continue
|
|
case "$file" in
|
|
*.json)
|
|
if [[ -f "$file" ]]; then
|
|
if ! json_ok "$file"; then
|
|
echo "validate-commit: invalid JSON: $file" >&2
|
|
JSON_FAILED=1
|
|
fi
|
|
fi
|
|
;;
|
|
esac
|
|
done <<<"$STAGED"
|
|
if [[ "$JSON_FAILED" == "1" ]]; then
|
|
fail "staged JSON validation failed"
|
|
fi
|
|
|
|
GD_FAILED=0
|
|
while IFS= read -r file; do
|
|
[[ -z "$file" ]] && continue
|
|
case "$file" in
|
|
*.gd)
|
|
if [[ -f "$file" ]]; then
|
|
if grep -qE '^(<<<<<<<|>>>>>>>|\|\|\|\|\|\|)' "$file"; then
|
|
echo "validate-commit: conflict markers in $file" >&2
|
|
GD_FAILED=1
|
|
fi
|
|
# Obvious type-consistency slips: int := quoted string, String := bare number.
|
|
if grep -qE 'var\s+[A-Za-z_][A-Za-z0-9_]*\s*:\s*int\s*=\s*"' "$file"; then
|
|
echo "validate-commit: type mismatch (int := string) in $file" >&2
|
|
GD_FAILED=1
|
|
fi
|
|
if grep -qE 'var\s+[A-Za-z_][A-Za-z0-9_]*\s*:\s*String\s*=\s*[0-9]' "$file"; then
|
|
echo "validate-commit: type mismatch (String := number) in $file" >&2
|
|
GD_FAILED=1
|
|
fi
|
|
fi
|
|
;;
|
|
esac
|
|
done <<<"$STAGED"
|
|
if [[ "$GD_FAILED" == "1" ]]; then
|
|
fail "staged GDScript check failed"
|
|
fi
|
|
|
|
if [[ "$RUN_TESTS" == "1" ]]; then
|
|
if command -v bun >/dev/null 2>&1; then
|
|
echo "validate-commit: running bun tests..."
|
|
if ! bun test ./packages/plugin/test/ ./companion/tests/; then
|
|
fail "tests failed, commit blocked"
|
|
fi
|
|
else
|
|
echo "validate-commit: warning: bun not found, skipping tests" >&2
|
|
fi
|
|
fi
|
|
|
|
echo "validate-commit: ok"
|
|
exit 0
|