Add git hooks check to bd doctor
- Adds checkGitHooks() function to verify recommended hooks are installed - Checks for pre-commit, post-merge, and pre-push hooks - Warns if hooks are missing with install instructions - Shows up early in diagnostics (even if .beads/ missing) - Includes comprehensive test coverage - Filed bd-6049 for broken --json flag 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,7 @@ This command checks:
|
||||
- Database-JSONL sync status
|
||||
- File permissions
|
||||
- Circular dependencies
|
||||
- Git hooks (pre-commit, post-merge, pre-push)
|
||||
|
||||
Examples:
|
||||
bd doctor # Check current directory
|
||||
@@ -107,7 +108,15 @@ func runDiagnostics(path string) doctorResult {
|
||||
result.Checks = append(result.Checks, installCheck)
|
||||
if installCheck.Status != statusOK {
|
||||
result.OverallOK = false
|
||||
// If no .beads/, skip other checks
|
||||
}
|
||||
|
||||
// Check Git Hooks early (even if .beads/ doesn't exist yet)
|
||||
hooksCheck := checkGitHooks(path)
|
||||
result.Checks = append(result.Checks, hooksCheck)
|
||||
// Don't fail overall check for missing hooks, just warn
|
||||
|
||||
// If no .beads/, skip remaining checks
|
||||
if installCheck.Status != statusOK {
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -956,6 +965,65 @@ func checkDependencyCycles(path string) doctorCheck {
|
||||
}
|
||||
}
|
||||
|
||||
func checkGitHooks(path string) doctorCheck {
|
||||
// Check if we're in a git repository
|
||||
gitDir := filepath.Join(path, ".git")
|
||||
if _, err := os.Stat(gitDir); os.IsNotExist(err) {
|
||||
return doctorCheck{
|
||||
Name: "Git Hooks",
|
||||
Status: statusOK,
|
||||
Message: "N/A (not a git repository)",
|
||||
}
|
||||
}
|
||||
|
||||
// Recommended hooks and their purposes
|
||||
recommendedHooks := map[string]string{
|
||||
"pre-commit": "Flushes pending bd changes to JSONL before commit",
|
||||
"post-merge": "Imports updated JSONL after git pull/merge",
|
||||
"pre-push": "Exports database to JSONL before push",
|
||||
}
|
||||
|
||||
hooksDir := filepath.Join(gitDir, "hooks")
|
||||
var missingHooks []string
|
||||
var installedHooks []string
|
||||
|
||||
for hookName := range recommendedHooks {
|
||||
hookPath := filepath.Join(hooksDir, hookName)
|
||||
if _, err := os.Stat(hookPath); os.IsNotExist(err) {
|
||||
missingHooks = append(missingHooks, hookName)
|
||||
} else {
|
||||
installedHooks = append(installedHooks, hookName)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingHooks) == 0 {
|
||||
return doctorCheck{
|
||||
Name: "Git Hooks",
|
||||
Status: statusOK,
|
||||
Message: "All recommended hooks installed",
|
||||
Detail: fmt.Sprintf("Installed: %s", strings.Join(installedHooks, ", ")),
|
||||
}
|
||||
}
|
||||
|
||||
if len(installedHooks) > 0 {
|
||||
return doctorCheck{
|
||||
Name: "Git Hooks",
|
||||
Status: statusWarning,
|
||||
Message: fmt.Sprintf("Missing %d recommended hook(s)", len(missingHooks)),
|
||||
Detail: fmt.Sprintf("Missing: %s", strings.Join(missingHooks, ", ")),
|
||||
Fix: "Run './examples/git-hooks/install.sh' to install recommended git hooks",
|
||||
}
|
||||
}
|
||||
|
||||
return doctorCheck{
|
||||
Name: "Git Hooks",
|
||||
Status: statusWarning,
|
||||
Message: "No recommended git hooks installed",
|
||||
Detail: fmt.Sprintf("Recommended: %s", strings.Join([]string{"pre-commit", "post-merge", "pre-push"}, ", ")),
|
||||
Fix: "Run './examples/git-hooks/install.sh' to install recommended git hooks",
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
doctorCmd.Flags().Bool("json", false, "Output JSON format")
|
||||
rootCmd.AddCommand(doctorCmd)
|
||||
|
||||
Reference in New Issue
Block a user