Skip to content

Commit 073ad51

Browse files
committed
support diff options
1 parent 393733f commit 073ad51

File tree

12 files changed

+161
-142
lines changed

12 files changed

+161
-142
lines changed

Gopkg.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626

2727

2828
[[constraint]]
29-
name = "github.com/bradleyfalzon/revgrep"
30-
version = "0.3.0"
29+
name = "github.com/golangci/revgrep"
30+
branch = "master"
3131

3232
[[constraint]]
3333
name = "github.com/stretchr/testify"

internal/commands/run.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ func (e *Executor) initRun() {
8383
runCmd.Flags().StringSliceVarP(&rc.ExcludePatterns, "exclude", "e", config.DefaultExcludePatterns, "Exclude issue by regexp")
8484

8585
runCmd.Flags().IntVar(&rc.MaxIssuesPerLinter, "max-issues-per-linter", 50, "Maximum issues count per one linter. Set to 0 to disable")
86+
87+
runCmd.Flags().BoolVarP(&rc.Diff, "new", "n", false, "Show only new issues: if there are unstaged changes or untracked files, only those changes are shown, else only changes in HEAD~ are shown")
88+
runCmd.Flags().StringVar(&rc.DiffFromRevision, "new-from-rev", "", "Show only new issues created after git revision `REV`")
89+
runCmd.Flags().StringVar(&rc.DiffPatchFilePath, "new-from-patch", "", "Show only new issues created in git patch with file path `PATH`")
8690
}
8791

8892
func isFullImportNeeded(linters []pkg.Linter) bool {
@@ -196,10 +200,11 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (chan result.
196200

197201
runner := pkg.SimpleRunner{
198202
Processors: []processors.Processor{
199-
processors.NewMaxPerFileFromLinter(),
200203
processors.NewExclude(fmt.Sprintf("(%s)", strings.Join(e.cfg.Run.ExcludePatterns, "|"))),
201204
processors.NewNolint(lintCtx.Program.Fset),
202205
processors.NewUniqByLine(),
206+
processors.NewDiff(e.cfg.Run.Diff, e.cfg.Run.DiffFromRevision, e.cfg.Run.DiffPatchFilePath),
207+
processors.NewMaxPerFileFromLinter(),
203208
processors.NewMaxFromLinter(e.cfg.Run.MaxIssuesPerLinter),
204209
processors.NewPathPrettifier(),
205210
},

pkg/config/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ type Run struct {
7979
Deadline time.Duration
8080

8181
MaxIssuesPerLinter int
82+
83+
DiffFromRevision string
84+
DiffPatchFilePath string
85+
Diff bool
8286
}
8387

8488
type Config struct {

pkg/result/issue.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ type Issue struct {
88
HunkPos int
99
}
1010

11+
func (i Issue) FilePath() string {
12+
return i.File
13+
}
14+
15+
func (i Issue) Line() int {
16+
return i.LineNumber
17+
}
18+
1119
func NewIssue(fromLinter, text, file string, lineNumber, hunkPos int) Issue {
1220
return Issue{
1321
FromLinter: fromLinter,

pkg/result/processors/diff.go

Lines changed: 40 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,66 @@
11
package processors
22

33
import (
4+
"bytes"
45
"fmt"
6+
"io"
57
"io/ioutil"
6-
"strings"
78

8-
"github.com/bradleyfalzon/revgrep"
99
"github.com/golangci/golangci-lint/pkg/result"
10+
"github.com/golangci/revgrep"
1011
)
1112

12-
type DiffProcessor struct {
13-
patch string
13+
type Diff struct {
14+
onlyNew bool
15+
fromRev string
16+
patchFilePath string
1417
}
1518

16-
func NewDiffProcessor(patch string) *DiffProcessor {
17-
return &DiffProcessor{
18-
patch: patch,
19+
var _ Processor = Diff{}
20+
21+
func NewDiff(onlyNew bool, fromRev, patchFilePath string) *Diff {
22+
return &Diff{
23+
onlyNew: onlyNew,
24+
fromRev: fromRev,
25+
patchFilePath: patchFilePath,
1926
}
2027
}
2128

22-
func (p DiffProcessor) Name() string {
29+
func (p Diff) Name() string {
2330
return "diff"
2431
}
2532

26-
func (p DiffProcessor) processResult(res result.Result) (*result.Result, error) {
27-
// Make mapping to restore original issues metadata later
28-
fli := makeFilesToLinesToIssuesMap([]result.Result{res})
29-
30-
rIssues, err := p.runRevgrepOnIssues(res.Issues)
31-
if err != nil {
32-
return nil, err
33-
}
34-
35-
newIssues := []result.Issue{}
36-
for _, ri := range rIssues {
37-
if fli[ri.File] == nil {
38-
return nil, fmt.Errorf("can't get original issue file for %v", ri)
39-
}
40-
41-
oi := fli[ri.File][ri.LineNo]
42-
if len(oi) != 1 {
43-
return nil, fmt.Errorf("can't get original issue for %v: %v", ri, oi)
44-
}
45-
46-
i := result.Issue{
47-
File: ri.File,
48-
LineNumber: ri.LineNo,
49-
Text: ri.Message,
50-
HunkPos: ri.HunkPos,
51-
FromLinter: oi[0].FromLinter,
52-
}
53-
newIssues = append(newIssues, i)
33+
func (p Diff) Process(issues []result.Issue) ([]result.Issue, error) {
34+
if !p.onlyNew && p.fromRev == "" && p.patchFilePath == "" { // no need to work
35+
return issues, nil
5436
}
5537

56-
res.Issues = newIssues
57-
return &res, nil
58-
}
59-
60-
func (p DiffProcessor) Process(results []result.Result) ([]result.Result, error) {
61-
retResults := []result.Result{}
62-
for _, res := range results {
63-
newRes, err := p.processResult(res)
38+
var patchReader io.Reader
39+
if p.patchFilePath != "" {
40+
patch, err := ioutil.ReadFile(p.patchFilePath)
6441
if err != nil {
65-
return nil, fmt.Errorf("can't filter only new issues for result %+v: %s", res, err)
42+
return nil, fmt.Errorf("can't read from pathc file %s: %s", p.patchFilePath, err)
6643
}
67-
retResults = append(retResults, *newRes)
44+
patchReader = bytes.NewReader(patch)
6845
}
69-
70-
return retResults, nil
71-
}
72-
73-
func (p DiffProcessor) runRevgrepOnIssues(issues []result.Issue) ([]revgrep.Issue, error) {
74-
// TODO: change revgrep to accept interface with line number, file name
75-
fakeIssuesLines := []string{}
76-
for _, i := range issues {
77-
line := fmt.Sprintf("%s:%d:%d: %s", i.File, i.LineNumber, 0, i.Text)
78-
fakeIssuesLines = append(fakeIssuesLines, line)
46+
c := revgrep.Checker{
47+
Patch: patchReader,
48+
RevisionFrom: p.fromRev,
7949
}
80-
fakeIssuesOut := strings.Join(fakeIssuesLines, "\n")
81-
82-
checker := revgrep.Checker{
83-
Patch: strings.NewReader(p.patch),
84-
Regexp: `^([^:]+):(\d+):(\d+)?:?\s*(.*)$`,
85-
}
86-
rIssues, err := checker.Check(strings.NewReader(fakeIssuesOut), ioutil.Discard)
87-
if err != nil {
88-
return nil, fmt.Errorf("can't filter only new issues by revgrep: %s", err)
50+
if err := c.Prepare(); err != nil {
51+
return nil, fmt.Errorf("can't prepare diff by revgrep: %s", err)
8952
}
9053

91-
return rIssues, nil
54+
return transformIssues(issues, func(i *result.Issue) *result.Issue {
55+
hunkPos, isNew := c.IsNewIssue(i)
56+
if !isNew {
57+
return nil
58+
}
59+
60+
newI := *i
61+
newI.HunkPos = hunkPos
62+
return &newI
63+
}), nil
9264
}
65+
66+
func (Diff) Finish() {}

pkg/result/processors/utils.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,6 @@ package processors
22

33
import "github.com/golangci/golangci-lint/pkg/result"
44

5-
type linesToIssuesMap map[int][]result.Issue
6-
type filesToLinesToIssuesMap map[string]linesToIssuesMap
7-
8-
func makeFilesToLinesToIssuesMap(results []result.Result) filesToLinesToIssuesMap {
9-
fli := filesToLinesToIssuesMap{}
10-
for _, res := range results {
11-
for _, i := range res.Issues {
12-
if fli[i.File] == nil {
13-
fli[i.File] = linesToIssuesMap{}
14-
}
15-
li := fli[i.File]
16-
li[i.LineNumber] = append(li[i.LineNumber], i)
17-
}
18-
}
19-
return fli
20-
}
21-
225
func filterIssues(issues []result.Issue, filter func(i *result.Issue) bool) []result.Issue {
236
retIssues := make([]result.Issue, 0, len(issues))
247
for _, i := range issues {

0 commit comments

Comments
 (0)