#!/usr/bin/env bash # Integration test for .pre-commit-hooks.yaml as an EXTERNAL hook repo — the # contract ADR-0014 exists to provide, and the one thing running pre-commit # inside this repo can never exercise: `repo: local` makes pre-commit's clone # prefix equal to the consuming repo's root, so a hook entry that only works # because those two coincide passes here and hard-fails everywhere else. # (It did: every argument after entry[0] resolves against the CONSUMING repo, # so a `--config plugins/.../.vale.ini` argument gave external consumers # `E100 [--config] Runtime error ... does not exist`, exit 2, on both Vale hooks.) # # The hook repo is built from the WORKING TREE, not from HEAD, so an uncommitted # change to the manifest or the wrapper is what gets tested. set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PASS=0 FAIL=0 pass() { echo " PASS: $1"; PASS=$((PASS + 1)); } fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); } for bin in pre-commit vale git; do if ! command -v "$bin" &>/dev/null; then echo "SKIP: $bin is not installed — cannot stand up a consumer repo" exit 77 fi done WORK="$(mktemp -d)" trap 'rm -rf "$WORK"' EXIT HOOK_REPO="$WORK/hookrepo" CONSUMER="$WORK/consumer" export PRE_COMMIT_HOME="$WORK/pc-home" mkdir -p "$HOOK_REPO/plugins/kyberforge/skills" "$HOOK_REPO/scripts" cp "$REPO_ROOT/.pre-commit-hooks.yaml" "$HOOK_REPO/" cp "$REPO_ROOT/scripts/skill-size-check.sh" "$HOOK_REPO/scripts/" for skill in skill-audit agent-audit; do mkdir -p "$HOOK_REPO/plugins/kyberforge/skills/$skill" cp -R "$REPO_ROOT/plugins/kyberforge/skills/$skill/scripts" \ "$REPO_ROOT/plugins/kyberforge/skills/$skill/assets" \ "$HOOK_REPO/plugins/kyberforge/skills/$skill/" done git -C "$HOOK_REPO" init -q git -C "$HOOK_REPO" add -A git -C "$HOOK_REPO" -c user.email=test@example.invalid -c user.name=test commit -qm "hook repo" HOOK_REV="$(git -C "$HOOK_REPO" rev-parse HEAD)" # The two Vale hooks scope by filename, so the consumer needs one file of each # shape: a hook with nothing to match reports `Skipped` and proves nothing. mkdir -p "$CONSUMER/skills/demo" "$CONSUMER/agents" git -C "$CONSUMER" init -q cat > "$CONSUMER/.pre-commit-config.yaml" < "$CONSUMER/skills/demo/SKILL.md" < Use when the caller wants a demonstration skill $body across two physical lines of one folded block scalar. --- Body. EOF cat > "$CONSUMER/agents/demo.md" < Use when the caller wants a demonstration agent $body across two physical lines of one folded block scalar. --- Body. EOF git -C "$CONSUMER" add -A } run_hooks() { (cd "$CONSUMER" && pre-commit run --all-files 2>&1) || true } # --- 1. Both hooks resolve their config and actually gate on a bad file --- echo "" echo "--- both Vale hooks run and fail a bad file in an external consumer repo ---" write_fixtures "that helps with and utilize things" OUT_BAD="$(run_hooks)" if echo "$OUT_BAD" | grep -q "does not exist"; then fail "hooks hard-errored on a path resolved against the consumer repo (E100) — the bug this test guards against" echo "$OUT_BAD" | sed 's/^/ /' elif echo "$OUT_BAD" | grep -q "Skipped"; then fail "a hook matched no files, so it proved nothing" echo "$OUT_BAD" | sed 's/^/ /' elif [[ "$(echo "$OUT_BAD" | grep -c "VagueWording")" -ge 2 ]]; then pass "both hooks flatten and flag the folded description in a consumer repo" else fail "hooks did not flag both fixtures" echo "$OUT_BAD" | sed 's/^/ /' fi # --- 2. Clean files pass — the hooks gate, they don't just always fail --- echo "" echo "--- both Vale hooks pass clean files in an external consumer repo ---" write_fixtures "of the packaged hook contract" set +e (cd "$CONSUMER" && pre-commit run --all-files > "$WORK/clean.log" 2>&1) RC_CLEAN=$? set -e if [[ $RC_CLEAN -eq 0 ]]; then pass "both hooks exit 0 on clean files" else fail "hooks failed on clean files (rc=$RC_CLEAN)" sed 's/^/ /' "$WORK/clean.log" fi echo "" echo "Results: $PASS passed, $FAIL failed" [[ $FAIL -eq 0 ]]