@@ -4,6 +4,7 @@ package revgrep
4
4
import (
5
5
"bufio"
6
6
"bytes"
7
+ "context"
7
8
"errors"
8
9
"fmt"
9
10
"io"
@@ -86,9 +87,11 @@ func (i simpleInputIssue) Line() int {
86
87
}
87
88
88
89
// Prepare extracts a patch and changed lines.
89
- func (c * Checker ) Prepare () error {
90
- returnErr := c .preparePatch ()
90
+ func (c * Checker ) Prepare (ctx context.Context ) error {
91
+ returnErr := c .preparePatch (ctx )
92
+
91
93
c .changes = c .linesChanged ()
94
+
92
95
return returnErr
93
96
}
94
97
@@ -119,7 +122,9 @@ func (c *Checker) IsNewIssue(i InputIssue) (hunkPos int, isNew bool) {
119
122
if changed || fchanges == nil {
120
123
// either file changed or it's a new file
121
124
hunkPos := fpos .lineNo
122
- if changed { // existing file changed
125
+
126
+ // existing file changed
127
+ if changed {
123
128
hunkPos = fpos .hunkPos
124
129
}
125
130
@@ -137,8 +142,8 @@ func (c *Checker) IsNewIssue(i InputIssue) (hunkPos int, isNew bool) {
137
142
// all issues are written to writer and an error is returned.
138
143
//
139
144
// File paths in reader must be relative to current working directory or absolute.
140
- func (c * Checker ) Check (reader io.Reader , writer io.Writer ) (issues []Issue , err error ) {
141
- returnErr := c .Prepare ()
145
+ func (c * Checker ) Check (ctx context. Context , reader io.Reader , writer io.Writer ) (issues []Issue , err error ) {
146
+ returnErr := c .Prepare (ctx )
142
147
writeAll := returnErr != nil
143
148
144
149
// file.go:lineNo:colNo:message
@@ -240,11 +245,11 @@ func (c *Checker) debugf(format string, s ...interface{}) {
240
245
}
241
246
}
242
247
243
- func (c * Checker ) preparePatch () error {
248
+ func (c * Checker ) preparePatch (ctx context. Context ) error {
244
249
// Check if patch is supplied, if not, retrieve from VCS
245
250
if c .Patch == nil {
246
251
var err error
247
- c .Patch , c .NewFiles , err = GitPatch (c .RevisionFrom , c .RevisionTo )
252
+ c .Patch , c .NewFiles , err = GitPatch (ctx , c .RevisionFrom , c .RevisionTo )
248
253
if err != nil {
249
254
return fmt .Errorf ("could not read git repo: %w" , err )
250
255
}
@@ -287,15 +292,19 @@ func (c *Checker) linesChanged() map[string][]pos {
287
292
// it's likey part of a file and not relevant to the patch.
288
293
continue
289
294
}
295
+
290
296
if err != nil {
291
297
scanErr = err
292
298
break
293
299
}
300
+
294
301
line := strings .TrimRight (string (lineB ), "\n " )
295
302
296
303
c .debugf (line )
304
+
297
305
s .lineNo ++
298
306
s .hunkPos ++
307
+
299
308
switch {
300
309
case strings .HasPrefix (line , "+++ " ) && len (line ) > 4 :
301
310
if s .changes != nil {
@@ -304,6 +313,7 @@ func (c *Checker) linesChanged() map[string][]pos {
304
313
}
305
314
// 6 removes "+++ b/"
306
315
s = state {file : line [6 :], hunkPos : - 1 , changes : []pos {}}
316
+
307
317
case strings .HasPrefix (line , "@@ " ):
308
318
// @@ -1 +2,4 @@
309
319
// chdr ^^^^^^^^^^^^^
@@ -317,8 +327,10 @@ func (c *Checker) linesChanged() map[string][]pos {
317
327
panic (err )
318
328
}
319
329
s .lineNo = int (cstart ) - 1 // -1 as cstart is the next line number
330
+
320
331
case strings .HasPrefix (line , "-" ):
321
332
s .lineNo --
333
+
322
334
case strings .HasPrefix (line , "+" ):
323
335
s .changes = append (s .changes , pos {lineNo : s .lineNo , hunkPos : s .hunkPos })
324
336
}
@@ -342,15 +354,15 @@ func (c *Checker) linesChanged() map[string][]pos {
342
354
// If revisionFrom is set but revisionTo is not,
343
355
// untracked files will be included, to exclude untracked files set revisionTo to HEAD~.
344
356
// It's incorrect to specify revisionTo without a revisionFrom.
345
- func GitPatch (revisionFrom , revisionTo string ) (io.Reader , []string , error ) {
357
+ func GitPatch (ctx context. Context , revisionFrom , revisionTo string ) (io.Reader , []string , error ) {
346
358
// check if git repo exists
347
- if err := exec .Command ( "git" , "status" , "--porcelain" ).Run (); err != nil {
359
+ if err := exec .CommandContext ( ctx , "git" , "status" , "--porcelain" ).Run (); err != nil {
348
360
// don't return an error, we assume the error is not repo exists
349
361
return nil , nil , nil
350
362
}
351
363
352
364
// make a patch for untracked files
353
- ls , err := exec .Command ( "git" , "ls-files" , "--others" , "--exclude-standard" ).CombinedOutput ()
365
+ ls , err := exec .CommandContext ( ctx , "git" , "ls-files" , "--others" , "--exclude-standard" ).CombinedOutput ()
354
366
if err != nil {
355
367
return nil , nil , fmt .Errorf ("error executing git ls-files: %w" , err )
356
368
}
@@ -376,7 +388,7 @@ func GitPatch(revisionFrom, revisionTo string) (io.Reader, []string, error) {
376
388
377
389
args = append (args , "--" )
378
390
379
- patch , errDiff := gitDiff (args ... )
391
+ patch , errDiff := gitDiff (ctx , args ... )
380
392
if errDiff != nil {
381
393
return nil , nil , errDiff
382
394
}
@@ -389,7 +401,7 @@ func GitPatch(revisionFrom, revisionTo string) (io.Reader, []string, error) {
389
401
}
390
402
391
403
// make a patch for unstaged changes
392
- patch , err := gitDiff ("--" )
404
+ patch , err := gitDiff (ctx , "--" )
393
405
if err != nil {
394
406
return nil , nil , err
395
407
}
@@ -403,18 +415,18 @@ func GitPatch(revisionFrom, revisionTo string) (io.Reader, []string, error) {
403
415
}
404
416
405
417
// check for changes in recent commit
406
- patch , err = gitDiff ("HEAD~" , "--" )
418
+ patch , err = gitDiff (ctx , "HEAD~" , "--" )
407
419
if err != nil {
408
420
return nil , nil , err
409
421
}
410
422
411
423
return patch , nil , nil
412
424
}
413
425
414
- func gitDiff (extraArgs ... string ) (* bytes.Buffer , error ) {
415
- cmd := exec .Command ( "git" , "diff" , "--color=never" , "--no-ext-diff" )
426
+ func gitDiff (ctx context. Context , extraArgs ... string ) (* bytes.Buffer , error ) {
427
+ cmd := exec .CommandContext ( ctx , "git" , "diff" , "--color=never" , "--no-ext-diff" )
416
428
417
- if isSupportedByGit (2 , 41 , 0 ) {
429
+ if isSupportedByGit (ctx , 2 , 41 , 0 ) {
418
430
cmd .Args = append (cmd .Args , "--default-prefix" )
419
431
}
420
432
@@ -443,8 +455,8 @@ func readAsError(buff io.Reader) error {
443
455
return errors .New (string (output ))
444
456
}
445
457
446
- func isSupportedByGit (major , minor , patch int ) bool {
447
- output , err := exec .Command ( "git" , "version" ).CombinedOutput ()
458
+ func isSupportedByGit (ctx context. Context , major , minor , patch int ) bool {
459
+ output , err := exec .CommandContext ( ctx , "git" , "version" ).CombinedOutput ()
448
460
if err != nil {
449
461
return false
450
462
}
0 commit comments