NEO-29: enforce test coverage checks in git hooks
Add a pre-commit guard that blocks commits missing required client/server test updates and Bruno requests for route/contract changes, and wire hook installers to install both pre-commit and pre-push hooks.pull/54/head
parent
b92b86a407
commit
c4b71aac0d
|
|
@ -192,7 +192,7 @@ On **Linux** (including GitHub Actions), the path must be **`gdUnit4`** with a c
|
|||
|
||||
**Dev (NEO-18):** **`dev_toggle_occluder_obstacle`** (default **Ctrl+Shift+K**) toggles the prototype `Obstacle` visibility/collision in **`main.gd`**. **F9** / **F10** are used by the embedded debugger; use this action instead when the game is running in the editor.
|
||||
|
||||
**Git hook (recommended):** install the repo’s local **pre-push** GDScript lint hook from the repo root (once per clone):
|
||||
**Git hooks (recommended):** install the repo’s local hooks from the repo root (once per clone):
|
||||
|
||||
```bash
|
||||
./scripts/install-git-hooks.sh
|
||||
|
|
@ -204,7 +204,12 @@ On **Windows** (PowerShell), same hook:
|
|||
pwsh -File scripts/install-git-hooks.ps1
|
||||
```
|
||||
|
||||
It runs **`gdlint client/scripts client/test`** and **`gdformat --check client/scripts client/test`** before each push. It prefers **`.venv-gd/bin/`** (Unix) or **`.venv-gd/Scripts/`** (Windows venv) when present; without that venv or a global install, the hook **fails** and blocks the push — same as CI.
|
||||
This installs:
|
||||
|
||||
- **pre-commit**: blocks commits when `client/scripts/*.gd` changes lack matching `client/test/*_test.gd` updates, or when server route/contract files change without corresponding `server/NeonSprawl.Server.Tests/` and `bruno/neon-sprawl-server/*.bru` updates.
|
||||
- **pre-push**: runs **`gdlint client/scripts client/test`** and **`gdformat --check client/scripts client/test`**.
|
||||
|
||||
The pre-push hook prefers **`.venv-gd/bin/`** (Unix) or **`.venv-gd/Scripts/`** (Windows venv) when present; without that venv or a global install, the hook **fails** and blocks the push — same as CI.
|
||||
|
||||
**If CI fails gdlint but your push succeeded:** the hook was not installed, **`gdlint`/`gdformat` were missing** when the hook ran, or push bypassed hooks (`--no-verify`).
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(git rev-parse --show-toplevel)"
|
||||
cd "$repo_root"
|
||||
|
||||
mapfile -t staged_files < <(git diff --cached --name-only --diff-filter=ACMR)
|
||||
if [[ ${#staged_files[@]} -eq 0 ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
has_staged_match() {
|
||||
local pattern="$1"
|
||||
for f in "${staged_files[@]}"; do
|
||||
if [[ "$f" =~ $pattern ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
server_route_like_changed=false
|
||||
if has_staged_match '^server/NeonSprawl\.Server/.*(Api\.cs|Dtos\.cs|Program\.cs)$'; then
|
||||
server_route_like_changed=true
|
||||
fi
|
||||
|
||||
if [[ "$server_route_like_changed" == true ]]; then
|
||||
if ! has_staged_match '^server/NeonSprawl\.Server\.Tests/'; then
|
||||
echo "pre-commit: server route/contract files changed but no server tests staged." >&2
|
||||
echo "Add or update tests under server/NeonSprawl.Server.Tests/ before commit." >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! has_staged_match '^bruno/neon-sprawl-server/.*\.bru$'; then
|
||||
echo "pre-commit: server route/contract files changed but no Bruno request staged." >&2
|
||||
echo "Add/update .bru requests under bruno/neon-sprawl-server/ before commit." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if has_staged_match '^client/scripts/.*\.gd$'; then
|
||||
if ! has_staged_match '^client/test/.*_test\.gd$'; then
|
||||
echo "pre-commit: client/scripts .gd changes require test updates in client/test/*_test.gd." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
|
@ -1,19 +1,30 @@
|
|||
# Installs repo pre-push hook (gdlint + gdformat). Same behavior as install-git-hooks.sh.
|
||||
# Installs repo pre-commit and pre-push hooks. Same behavior as install-git-hooks.sh.
|
||||
# Run from repo root: pwsh -File scripts/install-git-hooks.ps1
|
||||
$ErrorActionPreference = "Stop"
|
||||
$repoRoot = (git rev-parse --show-toplevel).Trim()
|
||||
$hookDir = Join-Path $repoRoot ".git/hooks"
|
||||
$preCommitHookPath = Join-Path $hookDir "pre-commit"
|
||||
$hookPath = Join-Path $hookDir "pre-push"
|
||||
New-Item -ItemType Directory -Force -Path $hookDir | Out-Null
|
||||
$unixRoot = $repoRoot -replace "\\", "/"
|
||||
$lines = @(
|
||||
$preCommitLines = @(
|
||||
"#!/bin/sh",
|
||||
"set -e",
|
||||
"repo_root=`"$unixRoot`"",
|
||||
'cd "$repo_root" || exit 1',
|
||||
'exec sh "$repo_root/scripts/git-hooks/pre-commit" "$@"'
|
||||
)
|
||||
$preCommitContent = ($preCommitLines -join "`n") + "`n"
|
||||
$pushLines = @(
|
||||
"#!/bin/sh",
|
||||
"set -e",
|
||||
"repo_root=`"$unixRoot`"",
|
||||
'cd "$repo_root" || exit 1',
|
||||
'exec sh "$repo_root/scripts/git-hooks/pre-push" "$@"'
|
||||
)
|
||||
$content = ($lines -join "`n") + "`n"
|
||||
$content = ($pushLines -join "`n") + "`n"
|
||||
$utf8 = New-Object System.Text.UTF8Encoding $false
|
||||
[System.IO.File]::WriteAllText($preCommitHookPath, $preCommitContent, $utf8)
|
||||
[System.IO.File]::WriteAllText($hookPath, $content, $utf8)
|
||||
Write-Host "Installed pre-commit hook at $preCommitHookPath"
|
||||
Write-Host "Installed pre-push hook at $hookPath"
|
||||
|
|
|
|||
|
|
@ -3,10 +3,19 @@ set -euo pipefail
|
|||
|
||||
repo_root="$(git rev-parse --show-toplevel)"
|
||||
hook_dir="$repo_root/.git/hooks"
|
||||
pre_commit_hook_path="$hook_dir/pre-commit"
|
||||
hook_path="$hook_dir/pre-push"
|
||||
|
||||
mkdir -p "$hook_dir"
|
||||
|
||||
cat >"$pre_commit_hook_path" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(git rev-parse --show-toplevel)"
|
||||
exec "$repo_root/scripts/git-hooks/pre-commit" "$@"
|
||||
EOF
|
||||
|
||||
cat >"$hook_path" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
|
@ -15,5 +24,7 @@ repo_root="$(git rev-parse --show-toplevel)"
|
|||
exec "$repo_root/scripts/git-hooks/pre-push" "$@"
|
||||
EOF
|
||||
|
||||
chmod +x "$pre_commit_hook_path"
|
||||
chmod +x "$hook_path"
|
||||
echo "Installed pre-commit hook at $pre_commit_hook_path"
|
||||
echo "Installed pre-push hook at $hook_path"
|
||||
|
|
|
|||
Loading…
Reference in New Issue