From cbf893ced062d5a3ae1f69e212cc32d61bae8b89 Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Tue, 21 Apr 2026 18:08:27 +1200 Subject: [PATCH] feat(hooks): add Husky git hooks for ui/goose2 (#8577) Co-authored-by: Claude Opus 4.6 (1M context) --- .husky/pre-commit | 30 ++++++++++++++++++-- .husky/pre-push | 71 ++++++++++++++++++++++++++++++++++++++++++++++ ui/goose2/justfile | 7 +++-- 3 files changed, 103 insertions(+), 5 deletions(-) create mode 100755 .husky/pre-push diff --git a/.husky/pre-commit b/.husky/pre-commit index 4e793eaacb..cc12bdb58f 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,8 +1,34 @@ +#!/usr/bin/env bash +set -e + # Only auto-format desktop TS code if relevant files are modified -if git diff --cached --name-only | grep -q "^ui/desktop/"; then +if git diff --cached --no-renames --name-only | grep -q "^ui/desktop/"; then if [ -d "ui/desktop" ]; then - cd ui/desktop && pnpm exec lint-staged + (cd ui/desktop && pnpm exec lint-staged) else echo "Warning: ui/desktop directory does not exist, skipping lint-staged" fi fi + +# Run goose2 checks if any staged files are under ui/goose2/ +if git diff --cached --no-renames --name-only | grep -q '^ui/goose2/'; then + if [ -d "ui/goose2" ]; then + REPO_ROOT="$(pwd)" + echo "Running goose2 pre-commit checks..." + + # Auto-format only staged files and re-stage them + STAGED_FILES=$(git diff --cached --no-renames --diff-filter=ACMR --name-only | grep '^ui/goose2/' | sed 's|^ui/goose2/||' || true) + if [ -n "$STAGED_FILES" ]; then + cd ui/goose2 + echo "$STAGED_FILES" | xargs npx biome format --write + echo "$STAGED_FILES" | xargs npx biome check --fix + cd "$REPO_ROOT" + git diff --cached --no-renames --diff-filter=ACMR --name-only | grep '^ui/goose2/' | xargs git add + fi + + # Run checks (biome check + file sizes + i18n + typecheck) + just goose2 check + else + echo "Warning: ui/goose2 directory does not exist, skipping goose2 checks" + fi +fi diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 0000000000..7e68deb749 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# Run goose2 pre-push checks if any commits being pushed include goose2 changes. + +# --- Helper functions --- + +# Check if any ref being pushed includes changes under a given path prefix. +# Reads git's pre-push stdin (local_ref local_oid remote_ref remote_oid). +push_touches() { + local prefix="$1" + local z40="0000000000000000000000000000000000000000" + + while read local_ref local_oid remote_ref remote_oid; do + [ "$local_oid" = "$z40" ] && continue # deleting ref + + if [ "$remote_oid" = "$z40" ]; then + # New branch — compare against the merge base with the default branch + range="$(git merge-base HEAD main 2>/dev/null || echo "$local_oid")...$local_oid" + else + range="$remote_oid...$local_oid" + fi + + if git diff --no-renames --name-only "$range" -- 2>/dev/null | grep -q "^${prefix}"; then + return 0 + fi + done + + return 1 +} + +# Run commands in parallel, exit 1 if any fail. +# Usage: run_parallel "label1" "cmd1" "label2" "cmd2" ... +run_parallel() { + local -a labels=() pids=() + while [[ $# -ge 2 ]]; do + labels+=("$1"); shift + ( eval "$1" ) & pids+=($!); shift + done + + local -a failed=() + for i in "${!pids[@]}"; do + wait "${pids[$i]}" || failed+=("${labels[$i]}") + done + + if [[ ${#failed[@]} -gt 0 ]]; then + echo "Failed: ${failed[*]}" + return 1 + fi +} + +# --- Hook body --- + +push_touches "ui/goose2/" || exit 0 + +echo "Detected ui/goose2/ changes — running pre-push checks..." + +run_parallel \ + "fmt-check" "just goose2 fmt-check" \ + "clippy" "just goose2 clippy" \ + "check" "just goose2 check" \ + "test" "just goose2 test" \ + "build" "just goose2 build" \ + "tauri-check" "just goose2 tauri-check" + +exit_code=$? + +if [ $exit_code -eq 0 ]; then + echo "All goose2 pre-push checks passed." +else + echo "goose2 pre-push checks failed." + exit 1 +fi diff --git a/ui/goose2/justfile b/ui/goose2/justfile index 47e47c4f58..ef36cd2418 100644 --- a/ui/goose2/justfile +++ b/ui/goose2/justfile @@ -8,8 +8,9 @@ default: # ── Dev Environment ────────────────────────────────────────── -# Install dependencies and build workspace packages +# Install dependencies, build workspace packages, and activate git hooks setup: + git config core.hooksPath .husky cd ../ && pnpm install cd ../sdk && pnpm build cargo build --manifest-path ../../Cargo.toml -p goose-cli --bin goose @@ -33,7 +34,7 @@ fmt-check: # Run clippy on Tauri backend clippy: - cd src-tauri && cargo clippy -- -D warnings + cd src-tauri && TAURI_CONFIG='{"bundle":{"externalBin":[]}}' cargo clippy -- -D warnings # Build the frontend build: @@ -45,7 +46,7 @@ tauri-fmt-check: # Check Tauri Rust types tauri-check: - cd src-tauri && cargo check + cd src-tauri && TAURI_CONFIG='{"bundle":{"externalBin":[]}}' cargo check # Full CI gate ci: check clippy test build tauri-check