File: pluginhook.go

package info (click to toggle)
pluginhook 0~20150216.0~a320158-2
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 140 kB
  • ctags: 9
  • sloc: sh: 57; makefile: 24; python: 2; ruby: 1
file content (93 lines) | stat: -rw-r--r-- 2,025 bytes parent folder | download
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main

import (
	"os"
	"fmt"
	"os/exec"
	"syscall"
	"path/filepath"
	"log"
	"flag"
	"bytes"
	"strings"
	"golang.org/x/crypto/ssh/terminal"
)

func main() {
	var parallel = flag.Bool("p", false, "Run hooks in parallel")
	var trace = flag.Bool("x", false, "Trace mode")
	flag.Parse()

	if len(os.Getenv("PLUGINHOOK_TRACE")) > 0 {
		*trace = true
	}

	pluginPath := os.Getenv("PLUGIN_PATH")
	if pluginPath == "" {
		log.Fatal("[ERROR] Unable to locate plugins: set $PLUGIN_PATH\n")
		os.Exit(1)
	}
	if flag.NArg() < 1 {
		log.Fatal("[ERROR] Hook name argument is required\n")
		os.Exit(1)
	}
	cmds := make([]exec.Cmd, 0)
	var matches, _ = filepath.Glob(fmt.Sprintf("%s/*/%s", pluginPath, flag.Arg(0)))
	for _, hook := range matches {
		cmd := exec.Command(hook, flag.Args()[1:]...)
		cmds = append(cmds, *cmd)
	}
	for i := len(cmds)-1; i >= 0; i-- {
		cmds[i].Stderr = os.Stderr

		if i == len(cmds)-1 {
			cmds[i].Stdout = os.Stdout
		}
		if i > 0 {
			if *parallel {
				stdout, err := cmds[i-1].StdoutPipe()
				if err != nil {
					log.Fatal(err)
				}
				cmds[i].Stdin = stdout
			} else {
				var buf bytes.Buffer
				cmds[i-1].Stdout = &buf
				cmds[i].Stdin = &buf
			}
		}
		if i == 0 && !terminal.IsTerminal(syscall.Stdin) {
			cmds[i].Stdin = os.Stdin
		}
	}

	if *parallel {
		done := make(chan bool, len(cmds))

		for i := 0; i < len(cmds); i++ {
			go func(cmd exec.Cmd, i int) {
				if *trace {
					fmt.Fprintln(os.Stderr, "+", strings.Join(cmds[i].Args, " "))
				}
				err := cmd.Run()
				if msg, ok := err.(*exec.ExitError); ok { // there is error code 
					os.Exit(msg.Sys().(syscall.WaitStatus).ExitStatus())
				}
				done <- true
			}(cmds[i], i)
		}
		for i := 0; i < len(cmds); i++ {
			<-done
		}
	} else {
		for i := 0; i < len(cmds); i++ {
			if *trace {
				fmt.Fprintln(os.Stderr, "+", strings.Join(cmds[i].Args, " "))
			}
			err := cmds[i].Run()
			if msg, ok := err.(*exec.ExitError); ok { // there is error code 
				os.Exit(msg.Sys().(syscall.WaitStatus).ExitStatus())
			}
		}
	}
}