|
| 1 | +[CmdletBinding()] |
| 2 | +param( |
| 3 | + [switch]$Uninstall, |
| 4 | + [switch]$Force |
| 5 | +) |
| 6 | + |
| 7 | +Set-StrictMode -Version Latest |
| 8 | +$ErrorActionPreference = "Stop" |
| 9 | + |
| 10 | +$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..") |
| 11 | +$gitDir = Join-Path $repoRoot ".git" |
| 12 | + |
| 13 | +if (-not (Test-Path $gitDir)) { |
| 14 | + throw "No .git directory found at $gitDir. Run from inside a Git clone." |
| 15 | +} |
| 16 | + |
| 17 | +$hookDir = Join-Path $gitDir "hooks" |
| 18 | +$hookPath = Join-Path $hookDir "pre-commit" |
| 19 | +$backupPath = Join-Path $hookDir "pre-commit.grace.bak" |
| 20 | +$marker = "Grace Validate Hook" |
| 21 | + |
| 22 | +function Get-FileContent([string]$Path) { |
| 23 | + if (-not (Test-Path $Path)) { |
| 24 | + return "" |
| 25 | + } |
| 26 | + |
| 27 | + return (Get-Content -Path $Path -Raw) |
| 28 | +} |
| 29 | + |
| 30 | +function Write-Hook([string]$Path) { |
| 31 | + $hook = @" |
| 32 | +#!/usr/bin/env sh |
| 33 | +# Grace Validate Hook (installed by scripts/install-githooks.ps1) |
| 34 | +# Runs validate -Fast after any existing hook logic. |
| 35 | +
|
| 36 | +HOOK_DIR=$(cd "$(dirname "$0")" && pwd) |
| 37 | +BACKUP="$HOOK_DIR/pre-commit.grace.bak" |
| 38 | +
|
| 39 | +if [ -x "$BACKUP" ]; then |
| 40 | + "$BACKUP" "$@" || exit $? |
| 41 | +fi |
| 42 | +
|
| 43 | +if command -v pwsh >/dev/null 2>&1; then |
| 44 | + REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) |
| 45 | + if [ -n "$REPO_ROOT" ]; then |
| 46 | + pwsh -NoProfile -ExecutionPolicy Bypass -File "$REPO_ROOT/scripts/validate.ps1" -Fast || exit $? |
| 47 | + else |
| 48 | + echo "Grace hook: unable to locate repo root; skipping validate." >&2 |
| 49 | + fi |
| 50 | +else |
| 51 | + echo "Grace hook: pwsh not found; skipping validate." >&2 |
| 52 | +fi |
| 53 | +"@ |
| 54 | + |
| 55 | + Set-Content -Path $Path -Value $hook -Encoding ASCII |
| 56 | +} |
| 57 | + |
| 58 | +if ($Uninstall) { |
| 59 | + $current = Get-FileContent $hookPath |
| 60 | + |
| 61 | + if ($current -match $marker) { |
| 62 | + if (Test-Path $backupPath) { |
| 63 | + Copy-Item -Path $backupPath -Destination $hookPath -Force |
| 64 | + Remove-Item -Path $backupPath -Force |
| 65 | + Write-Host "Restored original pre-commit hook." |
| 66 | + } else { |
| 67 | + Remove-Item -Path $hookPath -Force |
| 68 | + Write-Host "Removed Grace pre-commit hook." |
| 69 | + } |
| 70 | + } else { |
| 71 | + Write-Host "Grace pre-commit hook not installed. No changes made." |
| 72 | + } |
| 73 | + |
| 74 | + return |
| 75 | +} |
| 76 | + |
| 77 | +$existing = Get-FileContent $hookPath |
| 78 | +if ($existing -match $marker) { |
| 79 | + Write-Host "Grace pre-commit hook already installed." |
| 80 | + return |
| 81 | +} |
| 82 | + |
| 83 | +if (Test-Path $hookPath) { |
| 84 | + if ((Test-Path $backupPath) -and -not $Force) { |
| 85 | + throw "Backup already exists at $backupPath. Use -Force to overwrite." |
| 86 | + } |
| 87 | + |
| 88 | + Copy-Item -Path $hookPath -Destination $backupPath -Force |
| 89 | +} |
| 90 | + |
| 91 | +Write-Hook $hookPath |
| 92 | +Write-Host "Installed Grace pre-commit hook (validate -Fast)." |
| 93 | +Write-Host "Run with -Uninstall to restore the previous hook." |
0 commit comments