@@ -3,8 +3,11 @@ package golinters
33import (
44 "fmt"
55 "strings"
6+ "sync"
67
7- gci "github.com/daixiang0/gci/pkg/analyzer"
8+ gcicfg "github.com/daixiang0/gci/pkg/configuration"
9+ "github.com/daixiang0/gci/pkg/gci"
10+ "github.com/pkg/errors"
811 "golang.org/x/tools/go/analysis"
912
1013 "github.com/golangci/golangci-lint/pkg/config"
@@ -15,33 +18,121 @@ import (
1518const gciName = "gci"
1619
1720func NewGci (settings * config.GciSettings ) * goanalysis.Linter {
18- var linterCfg map [string ]map [string ]interface {}
21+ var mu sync.Mutex
22+ var resIssues []goanalysis.Issue
23+
24+ analyzer := & analysis.Analyzer {
25+ Name : gciName ,
26+ Doc : goanalysis .TheOnlyanalyzerDoc ,
27+ Run : goanalysis .DummyRun ,
28+ }
29+
30+ var cfg * gci.GciConfiguration
1931 if settings != nil {
20- cfg := map [string ]interface {}{
21- gci .NoInlineCommentsFlag : settings .NoInlineComments ,
22- gci .NoPrefixCommentsFlag : settings .NoPrefixComments ,
23- gci .SectionsFlag : strings .Join (settings .Sections , gci .SectionDelimiter ),
24- gci .SectionSeparatorsFlag : strings .Join (settings .SectionSeparator , gci .SectionDelimiter ),
32+ rawCfg := gci.GciStringConfiguration {
33+ Cfg : gcicfg.FormatterConfiguration {
34+ NoInlineComments : settings .NoInlineComments ,
35+ NoPrefixComments : settings .NoPrefixComments ,
36+ },
37+ SectionStrings : settings .Sections ,
38+ SectionSeparatorStrings : settings .SectionSeparator ,
2539 }
2640
2741 if settings .LocalPrefixes != "" {
2842 prefix := []string {"standard" , "default" , fmt .Sprintf ("prefix(%s)" , settings .LocalPrefixes )}
29- cfg [ gci . SectionsFlag ] = strings . Join ( prefix , gci . SectionDelimiter )
43+ rawCfg . SectionStrings = prefix
3044 }
3145
32- linterCfg = map [string ]map [string ]interface {}{
33- gci .Analyzer .Name : cfg ,
34- }
46+ cfg , _ = rawCfg .Parse ()
3547 }
3648
49+ var lock sync.Mutex
50+
3751 return goanalysis .NewLinter (
3852 gciName ,
3953 "Gci controls golang package import order and makes it always deterministic." ,
40- []* analysis.Analyzer {gci . Analyzer },
41- linterCfg ,
54+ []* analysis.Analyzer {analyzer },
55+ nil ,
4256 ).WithContextSetter (func (lintCtx * linter.Context ) {
43- if settings .LocalPrefixes != "" {
44- lintCtx .Log .Warnf ("gci: `local-prefixes` is deprecated, use `sections` and `prefix(%s)` instead." , settings .LocalPrefixes )
57+ analyzer .Run = func (pass * analysis.Pass ) (interface {}, error ) {
58+ issues , err := runGci (pass , lintCtx , cfg , & lock )
59+ if err != nil {
60+ return nil , err
61+ }
62+
63+ if len (issues ) == 0 {
64+ return nil , nil
65+ }
66+
67+ mu .Lock ()
68+ resIssues = append (resIssues , issues ... )
69+ mu .Unlock ()
70+
71+ return nil , nil
4572 }
73+ }).WithIssuesReporter (func (* linter.Context ) []goanalysis.Issue {
74+ return resIssues
4675 }).WithLoadMode (goanalysis .LoadModeSyntax )
4776}
77+
78+ func runGci (pass * analysis.Pass , lintCtx * linter.Context , cfg * gci.GciConfiguration , lock * sync.Mutex ) ([]goanalysis.Issue , error ) {
79+ var fileNames []string
80+ for _ , f := range pass .Files {
81+ pos := pass .Fset .PositionFor (f .Pos (), false )
82+ fileNames = append (fileNames , pos .Filename )
83+ }
84+
85+ var diffs []string
86+ err := gci .DiffFormattedFilesToArray (fileNames , * cfg , & diffs , lock )
87+ if err != nil {
88+ return nil , err
89+ }
90+
91+ var issues []goanalysis.Issue
92+
93+ for _ , diff := range diffs {
94+ if diff == "" {
95+ continue
96+ }
97+
98+ is , err := extractIssuesFromPatch (diff , lintCtx , gciName )
99+ if err != nil {
100+ return nil , errors .Wrapf (err , "can't extract issues from gci diff output %s" , diff )
101+ }
102+
103+ for i := range is {
104+ issues = append (issues , goanalysis .NewIssue (& is [i ], pass ))
105+ }
106+ }
107+
108+ return issues , nil
109+ }
110+
111+ func getErrorTextForGci (settings config.GciSettings ) string {
112+ text := "File is not `gci`-ed"
113+
114+ hasOptions := settings .NoInlineComments || settings .NoPrefixComments || len (settings .Sections ) > 0 || len (settings .SectionSeparator ) > 0
115+ if ! hasOptions {
116+ return text
117+ }
118+
119+ text += " with"
120+
121+ if settings .NoInlineComments {
122+ text += " -NoInlineComments"
123+ }
124+
125+ if settings .NoPrefixComments {
126+ text += " -NoPrefixComments"
127+ }
128+
129+ if len (settings .Sections ) > 0 {
130+ text += " -s " + strings .Join (settings .Sections , "," )
131+ }
132+
133+ if len (settings .SectionSeparator ) > 0 {
134+ text += " -x " + strings .Join (settings .SectionSeparator , "," )
135+ }
136+
137+ return text
138+ }
0 commit comments