forked from reviewdog/reviewdog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
diff.go
71 lines (57 loc) · 1.27 KB
/
diff.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
package reviewdog
import (
"context"
"os/exec"
"sync"
)
var _ DiffService = &DiffString{}
type DiffString struct {
b []byte
strip int
}
func NewDiffString(diff string, strip int) DiffService {
return &DiffString{b: []byte(diff), strip: strip}
}
func (d *DiffString) Diff(_ context.Context) ([]byte, error) {
return d.b, nil
}
func (d *DiffString) Strip() int {
return d.strip
}
var _ DiffService = &DiffCmd{}
type DiffCmd struct {
cmd *exec.Cmd
strip int
out []byte
done bool
mu sync.RWMutex
}
func NewDiffCmd(cmd *exec.Cmd, strip int) *DiffCmd {
return &DiffCmd{cmd: cmd, strip: strip}
}
// Diff returns diff. It caches the result and can be used more than once.
func (d *DiffCmd) Diff(_ context.Context) ([]byte, error) {
d.mu.Lock()
defer d.mu.Unlock()
if d.done {
return d.out, nil
}
out, err := d.cmd.Output()
// Exit status of `git diff` is 1 if diff exists, so ignore the error if diff
// presents.
if err != nil && len(out) == 0 {
return nil, err
}
d.out = out
d.done = true
return d.out, nil
}
func (d *DiffCmd) Strip() int {
return d.strip
}
// EmptyDiff service return empty diff.
type EmptyDiff struct{}
func (*EmptyDiff) Diff(context.Context) ([]byte, error) {
return []byte{}, nil
}
func (*EmptyDiff) Strip() int { return 0 }