-
Notifications
You must be signed in to change notification settings - Fork 1
/
hook.go
60 lines (48 loc) · 1.04 KB
/
hook.go
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package hook
import (
"bytes"
"errors"
"os/exec"
"sync"
"github.com/cbroglie/mustache"
)
// NeedAuth is the `need_cert` hook
const NeedAuth = "need_auth"
// Start is the `start` hook
const Start = "start"
// Hook represents a configured hook
type Hook struct {
cmdLine string
lock sync.Mutex
state []byte
}
// New creates a new hook with an unparsed command line. The line
// will be
func New(cmdLine string) *Hook {
return &Hook{
cmdLine: cmdLine,
state: []byte{},
}
}
// Run the hook. if an exit value other than 0 occurs, the combined
// output will be returned in the error.
func (h *Hook) Run(attrs interface{}) error {
h.lock.Lock()
defer h.lock.Unlock()
out, err := mustache.Render(h.cmdLine, attrs)
if err != nil {
return err
}
stdout := bytes.Buffer{}
stderr := bytes.Buffer{}
cmd := exec.Command("sh", "-c", out)
cmd.Stdin = bytes.NewReader(h.state)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
return errors.New(string(stderr.Bytes()))
}
h.state = stdout.Bytes()
return nil
}