github.com/bgpat/reviewdog@v0.0.0-20230909064023-077e44ca1f66/diff.go (about) 1 package reviewdog 2 3 import ( 4 "context" 5 "os/exec" 6 "sync" 7 ) 8 9 var _ DiffService = &DiffString{} 10 11 type DiffString struct { 12 b []byte 13 strip int 14 } 15 16 func NewDiffString(diff string, strip int) DiffService { 17 return &DiffString{b: []byte(diff), strip: strip} 18 } 19 20 func (d *DiffString) Diff(_ context.Context) ([]byte, error) { 21 return d.b, nil 22 } 23 24 func (d *DiffString) Strip() int { 25 return d.strip 26 } 27 28 var _ DiffService = &DiffCmd{} 29 30 type DiffCmd struct { 31 cmd *exec.Cmd 32 strip int 33 out []byte 34 done bool 35 mu sync.RWMutex 36 } 37 38 func NewDiffCmd(cmd *exec.Cmd, strip int) *DiffCmd { 39 return &DiffCmd{cmd: cmd, strip: strip} 40 } 41 42 // Diff returns diff. It caches the result and can be used more than once. 43 func (d *DiffCmd) Diff(_ context.Context) ([]byte, error) { 44 d.mu.Lock() 45 defer d.mu.Unlock() 46 if d.done { 47 return d.out, nil 48 } 49 out, err := d.cmd.Output() 50 // Exit status of `git diff` is 1 if diff exists, so ignore the error if diff 51 // presents. 52 if err != nil && len(out) == 0 { 53 return nil, err 54 } 55 d.out = out 56 d.done = true 57 return d.out, nil 58 } 59 60 func (d *DiffCmd) Strip() int { 61 return d.strip 62 } 63 64 // EmptyDiff service return empty diff. 65 type EmptyDiff struct{} 66 67 func (*EmptyDiff) Diff(context.Context) ([]byte, error) { 68 return []byte{}, nil 69 } 70 71 func (*EmptyDiff) Strip() int { return 0 }