Add git hooks support and refactor info command
This commit is contained in:
107
cmd/bd/hooks.go
Normal file
107
cmd/bd/hooks.go
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const hookVersionPrefix = "# bd-hooks-version: "
|
||||||
|
|
||||||
|
// HookStatus represents the status of a single git hook
|
||||||
|
type HookStatus struct {
|
||||||
|
Name string
|
||||||
|
Installed bool
|
||||||
|
Version string
|
||||||
|
Outdated bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckGitHooks checks the status of bd git hooks in .git/hooks/
|
||||||
|
func CheckGitHooks() ([]HookStatus, error) {
|
||||||
|
hooks := []string{"pre-commit", "post-merge", "pre-push"}
|
||||||
|
statuses := make([]HookStatus, 0, len(hooks))
|
||||||
|
|
||||||
|
for _, hookName := range hooks {
|
||||||
|
status := HookStatus{
|
||||||
|
Name: hookName,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if hook exists
|
||||||
|
hookPath := filepath.Join(".git", "hooks", hookName)
|
||||||
|
version, err := getHookVersion(hookPath)
|
||||||
|
if err != nil {
|
||||||
|
// Hook doesn't exist or couldn't be read
|
||||||
|
status.Installed = false
|
||||||
|
} else {
|
||||||
|
status.Installed = true
|
||||||
|
status.Version = version
|
||||||
|
|
||||||
|
// Check if outdated (compare to current bd version)
|
||||||
|
if version != "" && version != Version {
|
||||||
|
status.Outdated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
statuses = append(statuses, status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return statuses, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getHookVersion extracts the version from a hook file
|
||||||
|
func getHookVersion(path string) (string, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
// Read first few lines looking for version marker
|
||||||
|
lineCount := 0
|
||||||
|
for scanner.Scan() && lineCount < 10 {
|
||||||
|
line := scanner.Text()
|
||||||
|
if strings.HasPrefix(line, hookVersionPrefix) {
|
||||||
|
version := strings.TrimSpace(strings.TrimPrefix(line, hookVersionPrefix))
|
||||||
|
return version, nil
|
||||||
|
}
|
||||||
|
lineCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
// No version found (old hook)
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatHookWarnings returns a formatted warning message if hooks are outdated
|
||||||
|
func FormatHookWarnings(statuses []HookStatus) string {
|
||||||
|
var warnings []string
|
||||||
|
|
||||||
|
missingCount := 0
|
||||||
|
outdatedCount := 0
|
||||||
|
|
||||||
|
for _, status := range statuses {
|
||||||
|
if !status.Installed {
|
||||||
|
missingCount++
|
||||||
|
} else if status.Outdated {
|
||||||
|
outdatedCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if missingCount > 0 {
|
||||||
|
warnings = append(warnings, fmt.Sprintf("⚠️ Git hooks not installed (%d missing)", missingCount))
|
||||||
|
warnings = append(warnings, " Run: examples/git-hooks/install.sh")
|
||||||
|
}
|
||||||
|
|
||||||
|
if outdatedCount > 0 {
|
||||||
|
warnings = append(warnings, fmt.Sprintf("⚠️ Git hooks are outdated (%d hooks)", outdatedCount))
|
||||||
|
warnings = append(warnings, " Run: examples/git-hooks/install.sh")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(warnings) > 0 {
|
||||||
|
return strings.Join(warnings, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
@@ -196,6 +196,14 @@ Examples:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check git hooks status
|
||||||
|
hookStatuses, err := CheckGitHooks()
|
||||||
|
if err == nil {
|
||||||
|
if warning := FormatHookWarnings(hookStatuses); warning != "" {
|
||||||
|
fmt.Printf("\n%s\n", warning)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# bd-hooks-version: 0.22.0
|
||||||
#
|
#
|
||||||
# bd (beads) post-merge hook
|
# bd (beads) post-merge hook
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# bd-hooks-version: 0.22.0
|
||||||
#
|
#
|
||||||
# bd (beads) pre-commit hook
|
# bd (beads) pre-commit hook
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# bd-hooks-version: 0.22.0
|
||||||
#
|
#
|
||||||
# bd (beads) pre-push hook
|
# bd (beads) pre-push hook
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user