#!/usr/bin/env bash set -euo pipefail # ECC Codex Git Hook: pre-push # Runs a lightweight verification flow before pushes. if [[ "${ECC_SKIP_GIT_HOOKS:-0}" == "1" || "${ECC_SKIP_PREPUSH:-0}" == "1" ]]; then exit 0 fi if [[ -f ".ecc-hooks-disable" || -f ".git/ecc-hooks-disable" ]]; then exit 0 fi if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then exit 0 fi ran_any_check=0 log() { printf '[ECC pre-push] %s\n' "$*" } fail() { printf '[ECC pre-push] FAILED: %s\n' "$*" >&2 exit 1 } detect_pm() { if [[ -f "pnpm-lock.yaml" ]]; then echo "pnpm" elif [[ -f "bun.lockb" ]]; then echo "bun" elif [[ -f "yarn.lock" ]]; then echo "yarn" elif [[ -f "package-lock.json" ]]; then echo "npm" else echo "npm" fi } has_node_script() { local script_name="$1" node -e 'const fs=require("fs"); const p=JSON.parse(fs.readFileSync("package.json","utf8")); process.exit(p.scripts && p.scripts[process.argv[1]] ? 0 : 1)' "$script_name" >/dev/null 2>&1 } run_node_script() { local pm="$1" local script_name="$2" case "$pm" in pnpm) pnpm run "$script_name" ;; bun) bun run "$script_name" ;; yarn) yarn "$script_name" ;; npm) npm run "$script_name" ;; *) npm run "$script_name" ;; esac } if [[ -f "package.json" ]]; then pm="$(detect_pm)" log "Node project detected (package manager: $pm)" for script_name in lint typecheck test build; do if has_node_script "$script_name"; then ran_any_check=1 log "Running: $script_name" run_node_script "$pm" "$script_name" || fail "$script_name failed" else log "Skipping missing script: $script_name" fi done if [[ "${ECC_PREPUSH_AUDIT:-0}" == "1" ]]; then ran_any_check=1 log "Running dependency audit (ECC_PREPUSH_AUDIT=1)" case "$pm" in pnpm) pnpm audit --prod || fail "pnpm audit failed" ;; bun) bun audit || fail "bun audit failed" ;; yarn) yarn npm audit --recursive || fail "yarn audit failed" ;; npm) npm audit --omit=dev || fail "npm audit failed" ;; *) npm audit --omit=dev || fail "npm audit failed" ;; esac fi fi if [[ -f "go.mod" ]] && command -v go >/dev/null 2>&1; then ran_any_check=1 log "Go project detected. Running: go test ./..." go test ./... || fail "go test failed" fi if [[ -f "pyproject.toml" || -f "requirements.txt" ]]; then if command -v pytest >/dev/null 2>&1; then ran_any_check=1 log "Python project detected. Running: pytest -q" pytest -q || fail "pytest failed" else log "Python project detected but pytest is not installed. Skipping." fi fi if [[ "$ran_any_check" -eq 0 ]]; then log "No supported checks found in this repository. Skipping." else log "Verification checks passed." fi exit 0