Installing kyberforge via the holocron marketplace caches the plugin at a specific version. After every push, the marketplace clone and plugin cache need to be refreshed manually — otherwise new skills added since the last install are invisible until the user runs `claude plugin update` manually. Adds a post-push git hook that pulls the holocron marketplace clone and updates the kyberforge cache automatically after every push, eliminating the manual refresh step. ## Implementation Notes - `scripts/git-hooks/post-push` is the canonical source; `install.sh` now copies all files in `scripts/git-hooks/` into `.git/hooks/` on fresh checkouts, making the pattern extensible for future hooks. - Hook exits 0 on all failures (warns to stderr) — a stale cache refresh never blocks a completed push. - 11 bats tests cover both the hook and the install.sh copy block, using mocked binaries and a temp-tree fixture to avoid touching real state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P87CiC58Ru2PPWYTeXtjHT
109 lines
3.3 KiB
Bash
Executable File
109 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
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)); }
|
|
|
|
HOOK="$REPO_ROOT/scripts/git-hooks/post-push"
|
|
FAKE_BIN="$(mktemp -d)"
|
|
FAKE_HOME="$(mktemp -d)"
|
|
trap 'rm -rf "$FAKE_BIN" "$FAKE_HOME"' EXIT
|
|
|
|
# Helper: write a fake git stub that exits with the given code
|
|
make_git() {
|
|
local exit_code="$1"
|
|
printf '#!/usr/bin/env bash\nexit %s\n' "$exit_code" > "$FAKE_BIN/git"
|
|
chmod +x "$FAKE_BIN/git"
|
|
}
|
|
|
|
# Helper: write a fake claude stub; optionally touches a sentinel file on invocation
|
|
make_claude() {
|
|
local exit_code="$1"
|
|
local log="${2:-}"
|
|
if [[ -n "$log" ]]; then
|
|
printf '#!/usr/bin/env bash\ntouch "%s"\nexit %s\n' "$log" "$exit_code" > "$FAKE_BIN/claude"
|
|
else
|
|
printf '#!/usr/bin/env bash\nexit %s\n' "$exit_code" > "$FAKE_BIN/claude"
|
|
fi
|
|
chmod +x "$FAKE_BIN/claude"
|
|
}
|
|
|
|
# Run the hook with mocked PATH and HOME; suppress all output
|
|
run_hook() {
|
|
PATH="$FAKE_BIN:$PATH" HOME="$FAKE_HOME" bash "$HOOK" > /dev/null 2>&1
|
|
}
|
|
|
|
# Run the hook and capture combined stdout+stderr
|
|
capture_hook() {
|
|
PATH="$FAKE_BIN:$PATH" HOME="$FAKE_HOME" bash "$HOOK" 2>&1 || true
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
echo "--- post-push: always exits 0 ---"
|
|
# ---------------------------------------------------------------------------
|
|
|
|
make_git 1; make_claude 0
|
|
if run_hook; then
|
|
pass "exits 0 when git pull fails"
|
|
else
|
|
fail "should exit 0 when git pull fails"
|
|
fi
|
|
|
|
make_git 0; make_claude 1
|
|
if run_hook; then
|
|
pass "exits 0 when claude plugin update fails"
|
|
else
|
|
fail "should exit 0 when claude plugin update fails"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
echo ""
|
|
echo "--- post-push: success output ---"
|
|
# ---------------------------------------------------------------------------
|
|
|
|
make_git 0; make_claude 0
|
|
output=$(capture_hook)
|
|
echo "$output" | grep -q "kyberforge cache updated" \
|
|
&& pass "prints success message when both git pull and claude succeed" \
|
|
|| fail "should print success message when both commands succeed"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
echo ""
|
|
echo "--- post-push: warnings on failure ---"
|
|
# ---------------------------------------------------------------------------
|
|
|
|
make_git 1; make_claude 0
|
|
output=$(capture_hook)
|
|
echo "$output" | grep -qi "failed to pull" \
|
|
&& pass "warns when git pull fails" \
|
|
|| fail "should warn when git pull fails"
|
|
|
|
make_git 0; make_claude 1
|
|
output=$(capture_hook)
|
|
echo "$output" | grep -qi "failed" \
|
|
&& pass "warns when claude plugin update fails" \
|
|
|| fail "should warn when claude plugin update fails"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
echo ""
|
|
echo "--- post-push: claude not called when git pull fails ---"
|
|
# ---------------------------------------------------------------------------
|
|
|
|
CLAUDE_LOG="$FAKE_HOME/claude-was-called"
|
|
make_git 1; make_claude 0 "$CLAUDE_LOG"
|
|
run_hook
|
|
if [[ ! -f "$CLAUDE_LOG" ]]; then
|
|
pass "claude not called when git pull fails"
|
|
else
|
|
fail "claude should not be called when git pull fails"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
echo ""
|
|
echo "Results: $PASS passed, $FAIL failed"
|
|
[[ $FAIL -eq 0 ]]
|