github.com/alexey-mercari/reviewdog@v0.10.1-0.20200514053941-928943b10766/filter.go (about) 1 package reviewdog 2 3 import ( 4 "path/filepath" 5 6 "github.com/reviewdog/reviewdog/diff" 7 "github.com/reviewdog/reviewdog/difffilter" 8 ) 9 10 // FilteredCheck represents CheckResult with filtering info. 11 type FilteredCheck struct { 12 *CheckResult 13 ShouldReport bool 14 LnumDiff int // 0 if the result is outside diff. 15 InDiffFile bool // false if the result is outside diff files. 16 OldPath string 17 OldLine int 18 } 19 20 // FilterCheck filters check results by diff. It doesn't drop check which 21 // is not in diff but set FilteredCheck.ShouldReport field false. 22 func FilterCheck(results []*CheckResult, diff []*diff.FileDiff, strip int, 23 cwd string, mode difffilter.Mode) []*FilteredCheck { 24 checks := make([]*FilteredCheck, 0, len(results)) 25 df := difffilter.New(diff, strip, cwd, mode) 26 for _, result := range results { 27 check := &FilteredCheck{CheckResult: result} 28 shouldReport, difffile, diffline := df.ShouldReport(result.Path, result.Lnum) 29 check.ShouldReport = shouldReport 30 if diffline != nil { 31 check.LnumDiff = diffline.LnumDiff 32 } 33 result.Path = CleanPath(result.Path, cwd) 34 if difffile != nil { 35 check.InDiffFile = true 36 check.OldPath, check.OldLine = getOldPosition(difffile, strip, result.Path, result.Lnum) 37 } 38 checks = append(checks, check) 39 } 40 return checks 41 } 42 43 // CleanPath clean up given path. If workdir is not empty, it returns relative 44 // path to the given workdir. 45 func CleanPath(path, workdir string) string { 46 p := path 47 if filepath.IsAbs(path) && workdir != "" { 48 relPath, err := filepath.Rel(workdir, path) 49 if err == nil { 50 p = relPath 51 } 52 } 53 p = filepath.Clean(p) 54 if p == "." { 55 return "" 56 } 57 return filepath.ToSlash(p) 58 } 59 60 func getOldPosition(filediff *diff.FileDiff, strip int, newPath string, newLine int) (oldPath string, oldLine int) { 61 if filediff == nil { 62 return "", 0 63 } 64 if difffilter.NormalizeDiffPath(filediff.PathNew, strip) != newPath { 65 return "", 0 66 } 67 oldPath = difffilter.NormalizeDiffPath(filediff.PathOld, strip) 68 delta := 0 69 for _, hunk := range filediff.Hunks { 70 if newLine < hunk.StartLineNew { 71 break 72 } 73 delta += hunk.LineLengthOld - hunk.LineLengthNew 74 for _, line := range hunk.Lines { 75 if line.LnumNew == newLine { 76 return oldPath, line.LnumOld 77 } 78 } 79 } 80 return oldPath, newLine + delta 81 }