Skip to content

Commit 3e09174

Browse files
bombsimontpounds
authored andcommitted
Add WSL linter (#771)
* Add WSL linter * Use v1.0.0 tag for wsl * Don't add specific test file skip, use mutex to add errors * Fix goimports error * Add more tests for WSL, bump WSL version * Fix bad go.sum (go mod tidy)
1 parent 30864f8 commit 3e09174

File tree

17 files changed

+1685
-3
lines changed

17 files changed

+1685
-3
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ stylecheck: Stylecheck is a replacement for golint [fast: true, auto-fix: false]
222222
unconvert: Remove unnecessary type conversions [fast: true, auto-fix: false]
223223
unparam: Reports unused function parameters [fast: true, auto-fix: false]
224224
whitespace: Tool for detection of leading and trailing whitespace [fast: true, auto-fix: true]
225+
wsl: Whitespace Linter - Forces you to use empty lines! [fast: true, auto-fix: false]
225226
```
226227
227228
Pass `-E/--enable` to enable linter and `-D/--disable` to disable:
@@ -469,6 +470,7 @@ golangci-lint help linters
469470
- [godox](https://github.com/matoous/godox) - Tool for detection of FIXME, TODO and other comment keywords
470471
- [funlen](https://github.com/ultraware/funlen) - Tool for detection of long functions
471472
- [whitespace](https://github.com/ultraware/whitespace) - Tool for detection of leading and trailing whitespace
473+
- [wsl](https://github.com/bombsimon/wsl) - Whitespace Linter - Forces you to use empty lines!
472474
473475
## Configuration
474476
@@ -1123,6 +1125,7 @@ Thanks to developers and authors of used linters:
11231125
- [leighmcculloch](https://github.com/leighmcculloch)
11241126
- [matoous](https://github.com/matoous)
11251127
- [ultraware](https://github.com/ultraware)
1128+
- [bombsimon](https://github.com/bombsimon)
11261129
11271130
## Changelog
11281131

go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.12
44

55
require (
66
github.com/OpenPeeDeeP/depguard v1.0.1
7+
github.com/bombsimon/wsl v1.0.1
78
github.com/fatih/color v1.7.0
89
github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db
910
github.com/go-lintpack/lintpack v0.5.2
@@ -40,7 +41,7 @@ require (
4041
github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517
4142
github.com/valyala/quicktemplate v1.2.0
4243
golang.org/x/tools v0.0.0-20190912215617-3720d1ec3678
43-
gopkg.in/yaml.v2 v2.2.2
44+
gopkg.in/yaml.v2 v2.2.4
4445
honnef.co/go/tools v0.0.1-2019.2.3
4546
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed
4647
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
1111
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
1212
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
1313
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
14+
github.com/bombsimon/wsl v1.0.1 h1:GkrpOj7ajds8re6EJXN+k6UtatYSktupigQ2ZfOUIOU=
15+
github.com/bombsimon/wsl v1.0.1/go.mod h1:DSRwCD8c7NecM11/LnZcTS8nS8OND5ybj04DWM4l8mc=
1416
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
1517
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
1618
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@@ -308,6 +310,8 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
308310
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
309311
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
310312
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
313+
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
314+
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
311315
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
312316
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
313317
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=

pkg/golinters/wsl.go

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package golinters
2+
3+
import (
4+
"sync"
5+
6+
"github.com/bombsimon/wsl"
7+
"golang.org/x/tools/go/analysis"
8+
9+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
10+
"github.com/golangci/golangci-lint/pkg/lint/linter"
11+
"github.com/golangci/golangci-lint/pkg/result"
12+
)
13+
14+
const (
15+
name = "wsl"
16+
)
17+
18+
// NewWSL returns a new WSL linter.
19+
func NewWSL() *goanalysis.Linter {
20+
var (
21+
issues []result.Issue
22+
mu = sync.Mutex{}
23+
analyzer = &analysis.Analyzer{
24+
Name: goanalysis.TheOnlyAnalyzerName,
25+
Doc: goanalysis.TheOnlyanalyzerDoc,
26+
}
27+
)
28+
29+
return goanalysis.NewLinter(
30+
name,
31+
"Whitespace Linter - Forces you to use empty lines!",
32+
[]*analysis.Analyzer{analyzer},
33+
nil,
34+
).WithContextSetter(func(lintCtx *linter.Context) {
35+
analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
36+
files := []string{}
37+
38+
for _, file := range pass.Files {
39+
files = append(files, pass.Fset.Position(file.Pos()).Filename)
40+
}
41+
42+
wslErrors, _ := wsl.ProcessFiles(files)
43+
if len(wslErrors) == 0 {
44+
return nil, nil
45+
}
46+
47+
mu.Lock()
48+
defer mu.Unlock()
49+
50+
for _, err := range wslErrors {
51+
issues = append(issues, result.Issue{
52+
FromLinter: name,
53+
Pos: err.Position,
54+
Text: err.Reason,
55+
})
56+
}
57+
58+
return nil, nil
59+
}
60+
}).WithIssuesReporter(func(*linter.Context) []result.Issue {
61+
return issues
62+
}).WithLoadMode(goanalysis.LoadModeSyntax)
63+
}

pkg/lint/lintersdb/manager.go

+3
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
204204
WithPresets(linter.PresetStyle).
205205
WithAutoFix().
206206
WithURL("https://github.com/ultraware/whitespace"),
207+
linter.NewConfig(golinters.NewWSL()).
208+
WithPresets(linter.PresetStyle).
209+
WithURL("https://github.com/bombsimon/wsl"),
207210
}
208211

209212
isLocalRun := os.Getenv("GOLANGCI_COM_RUN") == ""

test/testdata/wsl.go

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//args: -Ewsl
2+
//config: linters-settings.wsl.tests=1
3+
package testdata
4+
5+
import (
6+
"context"
7+
"fmt"
8+
)
9+
10+
func main() {
11+
var (
12+
y = 0
13+
)
14+
if y < 1 { // ERROR "if statements should only be cuddled with assignments"
15+
fmt.Println("tight")
16+
}
17+
18+
thisIsNotUsedInIf := true
19+
if 2 > 1 { // ERROR "if statements should only be cuddled with assignments used in the if statement itself"
20+
return
21+
}
22+
23+
one := 1
24+
two := 2
25+
three := 3
26+
if three == 3 { // ERROR "only one cuddle assignment allowed before if statement"
27+
fmt.Println("too many cuddled assignments", one, two, thisIsNotUsedInIf)
28+
}
29+
30+
var a = "a"
31+
var b = "b" // ERROR "declarations should never be cuddled"
32+
33+
if true {
34+
return
35+
}
36+
if false { // ERROR "if statements should only be cuddled with assignments"
37+
return
38+
}
39+
40+
for i := range make([]int, 10) {
41+
fmt.Println(i)
42+
fmt.Println(i + i)
43+
continue // ERROR "branch statements should not be cuddled if block has more than two lines"
44+
}
45+
46+
assignOne := a
47+
fmt.Println(assignOne)
48+
assignTwo := b // ERROR "assignments should only be cuddled with other assignments"
49+
fmt.Println(assignTwo)
50+
51+
_, cf1 := context.WithCancel(context.Background())
52+
_, cf2 := context.WithCancel(context.Background())
53+
defer cf1() // ERROR "only one cuddle assignment allowed before defer statement"
54+
defer cf2()
55+
}
56+
57+
func f1() int {
58+
x := 1
59+
return x
60+
}
61+
62+
func f2() int {
63+
x := 1
64+
y := 3
65+
return x + y // ERROR "return statements should not be cuddled if block has more than two lines"
66+
}
67+
68+
func f3() int {
69+
sum := 0
70+
for _, v := range []int{2, 4, 8} {
71+
sum += v
72+
}
73+
74+
notSum := 0
75+
for _, v := range []int{1, 2, 4} { // ERROR "ranges should only be cuddled with assignments used in the iteration"
76+
sum += v
77+
}
78+
79+
return sum + notSum
80+
}

vendor/github.com/bombsimon/wsl/.gitignore

+70
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/bombsimon/wsl/.travis.yml

+25
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/bombsimon/wsl/LICENSE

+21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)