Files
keyhunter/.planning/phases/07-import-cicd/07-05-SUMMARY.md
2026-04-05 23:59:32 +03:00

4.2 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, decisions, metrics, requirements
phase plan subsystem tags requires provides affects tech-stack key-files decisions metrics requirements
07-import-cicd 05 cmd/hook
cicd
git
pre-commit
hook
embed
cmd/root.go hookCmd registration
keyhunter hook install
keyhunter hook uninstall
embedded pre-commit script
cmd/stubs.go
added patterns
embed (stdlib)
go:embed compile-time script bundling
marker-based ownership detection
created modified
cmd/hook.go
cmd/hook_script.sh
cmd/hook_test.go
cmd/stubs.go
Use KEYHUNTER-HOOK v1 marker string to detect KeyHunter-owned hooks before overwrite/delete
Backup non-owned hooks on --force install instead of silent destruction (pre-commit.bak.<ts>)
Reuse same --force flag variable for install/uninstall since commands are mutually exclusive
Embed script via go:embed rather than string literal to preserve shell formatting and allow standalone editing
duration completed
~5m 2026-04-05
CICD-01

Phase 7 Plan 5: cmd/hook Install/Uninstall Summary

Git pre-commit hook lifecycle via keyhunter hook install/uninstall, with the pre-commit script bundled at compile time through go:embed.

What Was Built

  • cmd/hook.gohookCmd parent with install and uninstall subcommands, shared --force flag, .git/ validation via hookPath(), marker-aware overwrite/delete logic.
  • cmd/hook_script.sh — Embedded bash script carrying the KEYHUNTER-HOOK v1 marker. Reads staged files via git diff --cached --name-only --diff-filter=ACMR, pipes through xargs -r keyhunter scan --exit-code, propagates exit code to block commits on findings. Trailing newline preserved.
  • cmd/hook_test.go — 10 tests:
    • TestHookInstall_FreshRepo — mode 0o755, marker present
    • TestHookInstall_NotAGitRepo — error when no .git/
    • TestHookInstall_ExistingNonKeyhunterRefuses — refuses without --force
    • TestHookInstall_ForceBackupsExisting.bak.<ts> backup created
    • TestHookInstall_ExistingKeyhunterOverwrites — updates stale marker hook silently
    • TestHookUninstall_RemovesKeyhunter — install then remove lifecycle
    • TestHookUninstall_RefusesForeign — refuses non-marker file
    • TestHookUninstall_Force — removes foreign with --force
    • TestHookUninstall_Missing — no-op friendly message
    • TestHookScript_ContainsRequired — embedded script sanity check
  • cmd/stubs.go — Removed hookCmd stub block; kept every other stub.

Verification

go build ./...      # succeeds
go test ./cmd/... -run Hook -v
  10 tests, all PASS

Commit: aa8daf8

Deviations from Plan

Auto-fixed Issues

1. [Rule 3 - Blocking] Transient importCmd build error

  • Found during: Task 1 verification (go build)
  • Issue: Initial go build failed with undefined: importCmd because the stubs.go linter-driven update removed importCmd while cmd/import.go wasn't visible in the workspace yet.
  • Fix: Re-scanned workspace; cmd/import.go was present (plan 07-04's output), no action needed beyond ensuring stubs.go does not redeclare importCmd. Final go build succeeds.
  • Files modified: none beyond plan scope
  • Commit: aa8daf8 (same task commit)

Key Decisions

  • Marker string as ownership signal. KEYHUNTER-HOOK v1 in the script header lets uninstall/overwrite distinguish our hooks from user-authored ones without an external manifest file. The v1 suffix reserves space for future script format bumps.
  • Backup-on-force rather than destroy. --force install renames the existing hook to pre-commit.bak.<timestamp> instead of deleting, giving users a recovery path if they aimed the flag carelessly.
  • No global viper/config wiring. The hook commands are filesystem-only; introducing config loading would add surface area for zero benefit at this layer.

Files Created/Modified

  • Created: cmd/hook.go (~105 lines)
  • Created: cmd/hook_script.sh (20 lines)
  • Created: cmd/hook_test.go (~180 lines)
  • Modified: cmd/stubs.go (removed 6-line stub block)

Self-Check: PASSED

  • cmd/hook.go: FOUND
  • cmd/hook_script.sh: FOUND
  • cmd/hook_test.go: FOUND
  • Commit aa8daf8: FOUND
  • go build ./...: PASS
  • go test ./cmd/... -run Hook: 10/10 PASS
  • Stub removed from cmd/stubs.go: CONFIRMED