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.
|
**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
|
```bash
|
||||||
./scripts/install-git-hooks.sh
|
./scripts/install-git-hooks.sh
|
||||||
|
|
@ -204,7 +204,12 @@ On **Windows** (PowerShell), same hook:
|
||||||
pwsh -File scripts/install-git-hooks.ps1
|
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`).
|
**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
|
# Run from repo root: pwsh -File scripts/install-git-hooks.ps1
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
$repoRoot = (git rev-parse --show-toplevel).Trim()
|
$repoRoot = (git rev-parse --show-toplevel).Trim()
|
||||||
$hookDir = Join-Path $repoRoot ".git/hooks"
|
$hookDir = Join-Path $repoRoot ".git/hooks"
|
||||||
|
$preCommitHookPath = Join-Path $hookDir "pre-commit"
|
||||||
$hookPath = Join-Path $hookDir "pre-push"
|
$hookPath = Join-Path $hookDir "pre-push"
|
||||||
New-Item -ItemType Directory -Force -Path $hookDir | Out-Null
|
New-Item -ItemType Directory -Force -Path $hookDir | Out-Null
|
||||||
$unixRoot = $repoRoot -replace "\\", "/"
|
$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",
|
"#!/bin/sh",
|
||||||
"set -e",
|
"set -e",
|
||||||
"repo_root=`"$unixRoot`"",
|
"repo_root=`"$unixRoot`"",
|
||||||
'cd "$repo_root" || exit 1',
|
'cd "$repo_root" || exit 1',
|
||||||
'exec sh "$repo_root/scripts/git-hooks/pre-push" "$@"'
|
'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
|
$utf8 = New-Object System.Text.UTF8Encoding $false
|
||||||
|
[System.IO.File]::WriteAllText($preCommitHookPath, $preCommitContent, $utf8)
|
||||||
[System.IO.File]::WriteAllText($hookPath, $content, $utf8)
|
[System.IO.File]::WriteAllText($hookPath, $content, $utf8)
|
||||||
|
Write-Host "Installed pre-commit hook at $preCommitHookPath"
|
||||||
Write-Host "Installed pre-push hook at $hookPath"
|
Write-Host "Installed pre-push hook at $hookPath"
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,19 @@ set -euo pipefail
|
||||||
|
|
||||||
repo_root="$(git rev-parse --show-toplevel)"
|
repo_root="$(git rev-parse --show-toplevel)"
|
||||||
hook_dir="$repo_root/.git/hooks"
|
hook_dir="$repo_root/.git/hooks"
|
||||||
|
pre_commit_hook_path="$hook_dir/pre-commit"
|
||||||
hook_path="$hook_dir/pre-push"
|
hook_path="$hook_dir/pre-push"
|
||||||
|
|
||||||
mkdir -p "$hook_dir"
|
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'
|
cat >"$hook_path" <<'EOF'
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
@ -15,5 +24,7 @@ repo_root="$(git rev-parse --show-toplevel)"
|
||||||
exec "$repo_root/scripts/git-hooks/pre-push" "$@"
|
exec "$repo_root/scripts/git-hooks/pre-push" "$@"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$pre_commit_hook_path"
|
||||||
chmod +x "$hook_path"
|
chmod +x "$hook_path"
|
||||||
|
echo "Installed pre-commit hook at $pre_commit_hook_path"
|
||||||
echo "Installed pre-push hook at $hook_path"
|
echo "Installed pre-push hook at $hook_path"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue