@@ -4,6 +4,7 @@ package revgrep
44import (
55 "bufio"
66 "bytes"
7+ "context"
78 "errors"
89 "fmt"
910 "io"
@@ -86,9 +87,11 @@ func (i simpleInputIssue) Line() int {
8687}
8788
8889// 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+
9193 c .changes = c .linesChanged ()
94+
9295 return returnErr
9396}
9497
@@ -119,7 +122,9 @@ func (c *Checker) IsNewIssue(i InputIssue) (hunkPos int, isNew bool) {
119122 if changed || fchanges == nil {
120123 // either file changed or it's a new file
121124 hunkPos := fpos .lineNo
122- if changed { // existing file changed
125+
126+ // existing file changed
127+ if changed {
123128 hunkPos = fpos .hunkPos
124129 }
125130
@@ -137,8 +142,8 @@ func (c *Checker) IsNewIssue(i InputIssue) (hunkPos int, isNew bool) {
137142// all issues are written to writer and an error is returned.
138143//
139144// 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 )
142147 writeAll := returnErr != nil
143148
144149 // file.go:lineNo:colNo:message
@@ -240,11 +245,11 @@ func (c *Checker) debugf(format string, s ...interface{}) {
240245 }
241246}
242247
243- func (c * Checker ) preparePatch () error {
248+ func (c * Checker ) preparePatch (ctx context. Context ) error {
244249 // Check if patch is supplied, if not, retrieve from VCS
245250 if c .Patch == nil {
246251 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 )
248253 if err != nil {
249254 return fmt .Errorf ("could not read git repo: %w" , err )
250255 }
@@ -287,15 +292,19 @@ func (c *Checker) linesChanged() map[string][]pos {
287292 // it's likey part of a file and not relevant to the patch.
288293 continue
289294 }
295+
290296 if err != nil {
291297 scanErr = err
292298 break
293299 }
300+
294301 line := strings .TrimRight (string (lineB ), "\n " )
295302
296303 c .debugf (line )
304+
297305 s .lineNo ++
298306 s .hunkPos ++
307+
299308 switch {
300309 case strings .HasPrefix (line , "+++ " ) && len (line ) > 4 :
301310 if s .changes != nil {
@@ -304,6 +313,7 @@ func (c *Checker) linesChanged() map[string][]pos {
304313 }
305314 // 6 removes "+++ b/"
306315 s = state {file : line [6 :], hunkPos : - 1 , changes : []pos {}}
316+
307317 case strings .HasPrefix (line , "@@ " ):
308318 // @@ -1 +2,4 @@
309319 // chdr ^^^^^^^^^^^^^
@@ -317,8 +327,10 @@ func (c *Checker) linesChanged() map[string][]pos {
317327 panic (err )
318328 }
319329 s .lineNo = int (cstart ) - 1 // -1 as cstart is the next line number
330+
320331 case strings .HasPrefix (line , "-" ):
321332 s .lineNo --
333+
322334 case strings .HasPrefix (line , "+" ):
323335 s .changes = append (s .changes , pos {lineNo : s .lineNo , hunkPos : s .hunkPos })
324336 }
@@ -342,15 +354,15 @@ func (c *Checker) linesChanged() map[string][]pos {
342354// If revisionFrom is set but revisionTo is not,
343355// untracked files will be included, to exclude untracked files set revisionTo to HEAD~.
344356// 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 ) {
346358 // 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 {
348360 // don't return an error, we assume the error is not repo exists
349361 return nil , nil , nil
350362 }
351363
352364 // 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 ()
354366 if err != nil {
355367 return nil , nil , fmt .Errorf ("error executing git ls-files: %w" , err )
356368 }
@@ -376,7 +388,7 @@ func GitPatch(revisionFrom, revisionTo string) (io.Reader, []string, error) {
376388
377389 args = append (args , "--" )
378390
379- patch , errDiff := gitDiff (args ... )
391+ patch , errDiff := gitDiff (ctx , args ... )
380392 if errDiff != nil {
381393 return nil , nil , errDiff
382394 }
@@ -389,7 +401,7 @@ func GitPatch(revisionFrom, revisionTo string) (io.Reader, []string, error) {
389401 }
390402
391403 // make a patch for unstaged changes
392- patch , err := gitDiff ("--" )
404+ patch , err := gitDiff (ctx , "--" )
393405 if err != nil {
394406 return nil , nil , err
395407 }
@@ -403,18 +415,18 @@ func GitPatch(revisionFrom, revisionTo string) (io.Reader, []string, error) {
403415 }
404416
405417 // check for changes in recent commit
406- patch , err = gitDiff ("HEAD~" , "--" )
418+ patch , err = gitDiff (ctx , "HEAD~" , "--" )
407419 if err != nil {
408420 return nil , nil , err
409421 }
410422
411423 return patch , nil , nil
412424}
413425
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" )
416428
417- if isSupportedByGit (2 , 41 , 0 ) {
429+ if isSupportedByGit (ctx , 2 , 41 , 0 ) {
418430 cmd .Args = append (cmd .Args , "--default-prefix" )
419431 }
420432
@@ -443,8 +455,8 @@ func readAsError(buff io.Reader) error {
443455 return errors .New (string (output ))
444456}
445457
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 ()
448460 if err != nil {
449461 return false
450462 }
0 commit comments