-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
git.go
82 lines (69 loc) · 1.89 KB
/
git.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package git
import (
"bufio"
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/gitleaks/go-gitdiff/gitdiff"
"github.com/rs/zerolog/log"
)
// GitLog returns a channel of gitdiff.File objects from the git log -p command for the given source.
func GitLog(source string, logOpts string) (<-chan *gitdiff.File, error) {
sourceClean := filepath.Clean(source)
var cmd *exec.Cmd
if logOpts != "" {
args := []string{"-C", sourceClean, "log", "-p", "-U0"}
args = append(args, strings.Split(logOpts, " ")...)
cmd = exec.Command("git", args...)
} else {
cmd = exec.Command("git", "-C", sourceClean, "log", "-p", "-U0", "--full-history", "--simplify-merges", "--show-pulls", "--all")
}
log.Debug().Msgf("executing: %s", cmd.String())
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, err
}
if err := cmd.Start(); err != nil {
return nil, err
}
go listenForStdErr(stderr)
return gitdiff.Parse(stdout)
}
// GitDiff returns a channel of gitdiff.File objects from the git diff command for the given source.
func GitDiff(source string) (<-chan *gitdiff.File, error) {
sourceClean := filepath.Clean(source)
cmd := exec.Command("git", "-C", sourceClean, "diff", "-U0", ".")
log.Debug().Msgf("executing: %s", cmd.String())
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, err
}
if err := cmd.Start(); err != nil {
return nil, err
}
go listenForStdErr(stderr)
return gitdiff.Parse(stdout)
}
// listenForStdErr listens for stderr output from git and prints it to stdout
// then exits with exit code 1
func listenForStdErr(stderr io.ReadCloser) {
scanner := bufio.NewScanner(stderr)
errEncountered := false
for scanner.Scan() {
log.Error().Msg(scanner.Text())
errEncountered = true
}
if errEncountered {
os.Exit(1)
}
}