blob: de5d7e4c2db6de096c1f797e379dbfed929c194a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
// Package githook contains the shared implementation of Tailscale's git
// hooks. The tailscale/tailscale and tailscale/corp repositories each have
// a thin main package that dispatches to this one, calling individual
// hook functions with per-repo arguments as needed.
package githook
import (
_ "embed"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
)
// Launcher is the canonical bytes of launcher.sh. Downstream repos
// (e.g. tailscale/corp) rely on these bytes at install time.
//
//go:embed launcher.sh
var Launcher []byte
// RunLocalHook runs an optional user-supplied hook at
// .git/hooks/<name>.local, if present.
func RunLocalHook(hookName string, args []string) error {
cmdPath, err := os.Executable()
if err != nil {
return err
}
localHookPath := filepath.Join(filepath.Dir(cmdPath), hookName+".local")
if _, err := os.Stat(localHookPath); errors.Is(err, os.ErrNotExist) {
return nil
} else if err != nil {
return fmt.Errorf("checking for local hook: %w", err)
}
cmd := exec.Command(localHookPath, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("running local hook %q: %w", localHookPath, err)
}
return nil
}
|