all repos

mugit @ v0.3.0

🐮 git server that your cow will love

mugit/internal/git/hooks.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
setup per repo hooks, 22 days ago
1
package git
2
3
import (
4
	"fmt"
5
	"os"
6
	"os/exec"
7
	"path/filepath"
8
)
9
10
const hookDelegateScriptBody = `# AUTO GENERATED BY MUGIT, DO NOT MODIFY
11
data=$(cat)
12
exitcodes=""
13
hookname=$(basename "$0")
14
git_dir="${GIT_DIR:-$(dirname "$0")/..}"
15
16
for hook in "${git_dir}/hooks/${hookname}.d"/*; do
17
  test -x "${hook}" && test -f "${hook}" || continue
18
  echo "${data}" | "${hook}" "$@"
19
  exitcodes="${exitcodes} $?"
20
done
21
22
for i in ${exitcodes}; do
23
  [ ${i} -eq 0 ] || exit ${i}
24
done
25
`
26
27
var serverHookNames = []string{"pre-receive", "post-receive", "post-update", "update"}
28
29
func hookDelegateScript() (string, error) {
30
	bashPath, err := exec.LookPath("bash")
31
	if err != nil {
32
		return "", fmt.Errorf("failed to locate bash: %w", err)
33
	}
34
	return fmt.Sprintf("#!%s\n%s", bashPath, hookDelegateScriptBody), nil
35
}
36
37
// SetupHooks installs default server-side hook delegates for this repository.
38
func (g *Repo) SetupHooks() error {
39
	delegateScript, err := hookDelegateScript()
40
	if err != nil {
41
		return err
42
	}
43
44
	for _, hook := range serverHookNames {
45
		hookDir := filepath.Join(g.path, "hooks", hook+".d")
46
		if err := os.MkdirAll(hookDir, 0o755); err != nil {
47
			return fmt.Errorf("failed to create %s: %w", hookDir, err)
48
		}
49
50
		delegatePath := filepath.Join(g.path, "hooks", hook)
51
		if err := os.WriteFile(delegatePath, []byte(delegateScript), 0o755); err != nil {
52
			return fmt.Errorf("failed to write hook delegate %s: %w", delegatePath, err)
53
		}
54
	}
55
56
	return nil
57
}