Skip to content

Commit 75a5177

Browse files
committed
Introduce gci as new linter
Signed-off-by: Xiang Dai <long0dai@foxmail.com>
1 parent 206d79f commit 75a5177

File tree

6 files changed

+102
-7
lines changed

6 files changed

+102
-7
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ depguard: Go linter that checks if package imports are in a list of acceptable p
213213
dogsled: Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
214214
dupl: Tool for code clone detection [fast: true, auto-fix: false]
215215
funlen: Tool for detection of long functions [fast: true, auto-fix: false]
216+
gci: Ensure import order and automatic grouping [fast: false, auto-fix: false]
216217
gochecknoglobals: Checks that no globals are present in Go code [fast: true, auto-fix: false]
217218
gochecknoinits: Checks that no init functions are present in Go code [fast: true, auto-fix: false]
218219
gocognit: Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
@@ -503,6 +504,7 @@ golangci-lint help linters
503504
- [testpackage](https://github.com/maratori/testpackage) - linter that makes you use a separate _test package
504505
- [nestif](https://github.com/nakabonne/nestif) - Reports deeply nested if statements
505506
- [nolintlint](https://github.com/golangci-lint/pkg/golinters/nolintlint) - Reports ill-formed or insufficient nolint directives
507+
- [gci](https://github.com/daixiang0/gci) - Tool that control golang package import order and make it always deterministic
506508
507509
## Configuration
508510
@@ -1344,6 +1346,7 @@ Thanks to developers and authors of used linters:
13441346
- [maratori](https://github.com/maratori)
13451347
- [nakabonne](https://github.com/nakabonne)
13461348
- [golangci-lint](https://github.com/golangci-lint)
1349+
- [daixiang0](https://github.com/daixiang0)
13471350
13481351
## Changelog
13491352

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157
77
github.com/OpenPeeDeeP/depguard v1.0.1
88
github.com/bombsimon/wsl/v3 v3.0.0
9+
github.com/daixiang0/gci v0.0.0-20200724091831-0309acf4a76e
910
github.com/fatih/color v1.7.0
1011
github.com/go-critic/go-critic v0.4.1
1112
github.com/go-lintpack/lintpack v0.5.2
@@ -50,7 +51,7 @@ require (
5051
github.com/ultraware/whitespace v0.0.4
5152
github.com/uudashr/gocognit v1.0.1
5253
github.com/valyala/quicktemplate v1.2.0
53-
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770
54+
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305
5455
gopkg.in/yaml.v2 v2.2.8
5556
honnef.co/go/tools v0.0.1-2020.1.3
5657
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed

go.sum

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
2525
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
2626
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
2727
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
28+
github.com/daixiang0/gci v0.0.0-20200724091831-0309acf4a76e h1:KR0KKEJkLuCEA8kpg9JZOWvqN3y/Q8iWJ7bFJNvQSeY=
29+
github.com/daixiang0/gci v0.0.0-20200724091831-0309acf4a76e/go.mod h1:+AV8KmHTGxxwp/pY84TLQfFKp2vuKXXJVzF3kD/hfR4=
2830
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2931
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3032
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -223,8 +225,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
223225
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
224226
github.com/ryancurrah/gomodguard v1.0.4 h1:oCreMAt9GuFXDe9jW4HBpc3GjdX3R/sUEcLAGh1zPx8=
225227
github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE=
226-
github.com/securego/gosec/v2 v2.2.1-0.20200424144625-ee3146e63716 h1:E/qamk0wO4PVhJhce201hAJWk/rKnGqKOk/blHzkY7o=
227-
github.com/securego/gosec/v2 v2.2.1-0.20200424144625-ee3146e63716/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME=
228228
github.com/securego/gosec/v2 v2.3.0 h1:y/9mCF2WPDbSDpL3QDWZD3HHGrSYw0QSHnCqTfs4JPE=
229229
github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME=
230230
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I=
@@ -298,6 +298,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
298298
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
299299
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
300300
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
301+
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
301302
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
302303
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
303304
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -307,11 +308,14 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
307308
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
308309
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
309310
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
311+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
310312
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
311313
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
312314
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
313315
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
314316
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
317+
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
318+
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
315319
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
316320
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
317321
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -325,13 +329,16 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
325329
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
326330
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
327331
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
332+
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
333+
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
328334
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
329335
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
330336
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
331337
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
332338
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
333339
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
334340
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
341+
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
335342
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
336343
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
337344
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -344,6 +351,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
344351
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
345352
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
346353
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
354+
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
355+
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
347356
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
348357
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
349358
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -370,10 +379,8 @@ golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roY
370379
golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
371380
golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e h1:3Dzrrxi54Io7Aoyb0PYLsI47K2TxkRQg+cqUn+m04do=
372381
golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
373-
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE=
374-
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE=
375-
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE=
376-
golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
382+
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305 h1:yaM5S0KcY0lIoZo7Fl+oi91b/DdlU2zuWpfHrpWbCS0=
383+
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
377384
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
378385
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
379386
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=

pkg/golinters/gci.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package golinters
2+
3+
import (
4+
"sync"
5+
6+
"github.com/daixiang0/gci/pkg/analyzer"
7+
"github.com/daixiang0/gci/pkg/gci"
8+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
9+
"github.com/golangci/golangci-lint/pkg/lint/linter"
10+
"github.com/pkg/errors"
11+
"golang.org/x/tools/go/analysis"
12+
"golang.org/x/tools/imports"
13+
)
14+
15+
func NewGci() *goanalysis.Linter {
16+
var mu sync.Mutex
17+
var resIssues []goanalysis.Issue
18+
19+
analyzer := analyzer.Analyzer
20+
21+
return goanalysis.NewLinter(
22+
analyzer.Name,
23+
analyzer.Doc,
24+
analyzer.Requires,
25+
nil,
26+
).WithContextSetter(func(lintCtx *linter.Context) {
27+
imports.LocalPrefix = lintCtx.Settings().Goimports.LocalPrefixes
28+
analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
29+
var fileNames []string
30+
for _, f := range pass.Files {
31+
pos := pass.Fset.PositionFor(f.Pos(), false)
32+
fileNames = append(fileNames, pos.Filename)
33+
}
34+
35+
var issues []goanalysis.Issue
36+
for _, f := range fileNames {
37+
diff, err := gci.Run(f, &gci.FlagSet{})
38+
if err != nil {
39+
return nil, err
40+
}
41+
42+
if diff == nil {
43+
continue
44+
}
45+
46+
is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, analyzer.Name)
47+
if err != nil {
48+
return nil, errors.Wrapf(err, "can't extract issues from gci diff output %q", string(diff))
49+
}
50+
51+
for i := range is {
52+
issues = append(issues, goanalysis.NewIssue(&is[i], pass))
53+
}
54+
}
55+
56+
if len(issues) == 0 {
57+
return nil, nil
58+
}
59+
60+
mu.Lock()
61+
resIssues = append(resIssues, issues...)
62+
mu.Unlock()
63+
64+
return nil, nil
65+
}
66+
}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
67+
return resIssues
68+
}).WithLoadMode(goanalysis.LoadModeSyntax)
69+
}

pkg/lint/lintersdb/manager.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
193193
WithPresets(linter.PresetFormatting).
194194
WithAutoFix().
195195
WithURL("https://godoc.org/golang.org/x/tools/cmd/goimports"),
196+
linter.NewConfig(golinters.NewGci()).
197+
WithPresets(linter.PresetFormatting).
198+
WithURL("https://github.com/daixiang0/gci"),
196199
linter.NewConfig(golinters.NewMaligned()).
197200
WithLoadForGoAnalysis().
198201
WithPresets(linter.PresetPerformance).

test/testdata/gci.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//args: -Egci
2+
package testdata
3+
4+
import (
5+
"fmt" // ERROR "File is not `goimports`-ed"
6+
"github.com/golangci/golangci-lint/pkg/config"
7+
)
8+
9+
func Bar() {
10+
fmt.Print("x")
11+
_ = config.Config{}
12+
}

0 commit comments

Comments
 (0)