Skip to content

Commit 1aa3f1a

Browse files
authored
Merge pull request #6 from smacker/lll_configuration
Set max line length for lll linter from configuration
2 parents 6ca3335 + 59dc8e3 commit 1aa3f1a

3 files changed

Lines changed: 180 additions & 1 deletion

File tree

Gopkg.lock

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

analyzer.go

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package gometalint
22

33
import (
44
"context"
5+
"fmt"
56
"io/ioutil"
67
"os"
78
"path"
9+
"strconv"
810
"strings"
911

12+
types "github.com/gogo/protobuf/types"
1013
"github.com/src-d/lookout"
1114
log "gopkg.in/src-d/go-log.v1"
1215
)
@@ -22,6 +25,39 @@ type Analyzer struct {
2225

2326
var _ lookout.AnalyzerServer = &Analyzer{}
2427

28+
// function to convert pb.types.Value to string argument
29+
type argumentConstructor func(v *types.Value) string
30+
31+
// map of linters with options and argument constructors
32+
var lintersOptions = map[string]map[string]argumentConstructor{
33+
"lll": map[string]argumentConstructor{
34+
"maxLen": func(v *types.Value) string {
35+
var number int
36+
37+
switch v.GetKind().(type) {
38+
case *types.Value_StringValue:
39+
n, err := strconv.Atoi(v.GetStringValue())
40+
if err != nil {
41+
log.Warningf("wrong type for lll:maxLen argument")
42+
return ""
43+
}
44+
number = n
45+
case *types.Value_NumberValue:
46+
number = int(v.GetNumberValue())
47+
default:
48+
log.Warningf("wrong type for lll:maxLen argument")
49+
return ""
50+
}
51+
52+
if number < 1 {
53+
return ""
54+
}
55+
56+
return fmt.Sprintf("--line-length=%d", number)
57+
},
58+
},
59+
}
60+
2561
func (a *Analyzer) NotifyReviewEvent(ctx context.Context, e *lookout.ReviewEvent) (
2662
*lookout.EventResponse, error) {
2763
changes, err := a.DataClient.GetChanges(ctx, &lookout.ChangesRequest{
@@ -67,7 +103,7 @@ func (a *Analyzer) NotifyReviewEvent(ctx context.Context, e *lookout.ReviewEvent
67103
return &lookout.EventResponse{AnalyzerVersion: a.Version}, nil
68104
}
69105

70-
withArgs := append(a.Args, tmp)
106+
withArgs := append(append(a.Args, tmp), a.linterArguments(e.Configuration)...)
71107
comments := RunGometalinter(withArgs)
72108
var allComments []*lookout.Comment
73109
for _, comment := range comments {
@@ -106,3 +142,67 @@ func tryToSaveTo(file *lookout.File, tmp string) {
106142
func (a *Analyzer) NotifyPushEvent(ctx context.Context, e *lookout.PushEvent) (*lookout.EventResponse, error) {
107143
return &lookout.EventResponse{}, nil
108144
}
145+
146+
func (a *Analyzer) linterArguments(s types.Struct) []string {
147+
config := s.GetFields()
148+
if config == nil {
149+
return nil
150+
}
151+
152+
clStruct, ok := config["linters"]
153+
if !ok || clStruct == nil {
154+
return nil
155+
}
156+
157+
lintersListValue := clStruct.GetListValue()
158+
if lintersListValue == nil {
159+
return nil
160+
}
161+
162+
var args []string
163+
164+
for _, v := range lintersListValue.GetValues() {
165+
if v == nil {
166+
continue
167+
}
168+
169+
sv := v.GetStructValue()
170+
if sv == nil {
171+
continue
172+
}
173+
174+
fields := sv.GetFields()
175+
nameV, ok := fields["name"]
176+
if !ok || nameV == nil {
177+
continue
178+
}
179+
180+
name := nameV.GetStringValue()
181+
correctLinter := false
182+
for linter := range lintersOptions {
183+
if name == linter {
184+
correctLinter = true
185+
}
186+
}
187+
188+
if !correctLinter {
189+
log.Warningf("unknown linter %s", name)
190+
continue
191+
}
192+
193+
linterOpts := lintersOptions[name]
194+
for optionName := range linterOpts {
195+
optV, ok := fields[optionName]
196+
if !ok || optV == nil {
197+
continue
198+
}
199+
200+
arg := linterOpts[optionName](optV)
201+
if arg != "" {
202+
args = append(args, arg)
203+
}
204+
}
205+
}
206+
207+
return args
208+
}

analyzer_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package gometalint
2+
3+
import (
4+
"testing"
5+
6+
types "github.com/gogo/protobuf/types"
7+
"github.com/src-d/lookout/pb"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestArgsEmpty(t *testing.T) {
12+
require := require.New(t)
13+
14+
inputs := []types.Struct{
15+
types.Struct{},
16+
*pb.ToStruct(map[string]interface{}{
17+
"linters": []map[string]interface{}{},
18+
}),
19+
*pb.ToStruct(map[string]interface{}{
20+
"linters": []map[string]interface{}{
21+
{
22+
"name": "unknown",
23+
"maxLen": 120,
24+
},
25+
},
26+
}),
27+
*pb.ToStruct(map[string]interface{}{
28+
"linters": []map[string]interface{}{
29+
{
30+
"name": "lll",
31+
},
32+
},
33+
}),
34+
*pb.ToStruct(map[string]interface{}{
35+
"linters": []map[string]interface{}{
36+
{
37+
"name": "lll",
38+
"maxLen": "not a number",
39+
},
40+
},
41+
}),
42+
*pb.ToStruct(map[string]interface{}{
43+
"linters": []map[string]interface{}{
44+
{
45+
"name": "lll",
46+
"maxLen": 120.1,
47+
},
48+
},
49+
}),
50+
}
51+
52+
a := Analyzer{}
53+
for _, input := range inputs {
54+
require.Len(a.linterArguments(input), 0)
55+
}
56+
}
57+
58+
func TestArgsCorrect(t *testing.T) {
59+
a := Analyzer{}
60+
require.Equal(t, []string{"--line-length=120"}, a.linterArguments(*pb.ToStruct(map[string]interface{}{
61+
"linters": []map[string]interface{}{
62+
{
63+
"name": "lll",
64+
"maxLen": "120",
65+
},
66+
},
67+
})))
68+
69+
require.Equal(t, []string{"--line-length=120"}, a.linterArguments(*pb.ToStruct(map[string]interface{}{
70+
"linters": []map[string]interface{}{
71+
{
72+
"name": "lll",
73+
"maxLen": 120,
74+
},
75+
},
76+
})))
77+
}

0 commit comments

Comments
 (0)