@@ -2,12 +2,16 @@ package golinters
2
2
3
3
import (
4
4
"fmt"
5
+ "sort"
6
+ "strings"
5
7
"sync"
6
8
7
9
gcicfg "github.com/daixiang0/gci/pkg/config"
8
10
"github.com/daixiang0/gci/pkg/gci"
9
11
"github.com/daixiang0/gci/pkg/io"
10
12
"github.com/daixiang0/gci/pkg/log"
13
+ "github.com/daixiang0/gci/pkg/section"
14
+ "github.com/golangci/modinfo"
11
15
"github.com/hexops/gotextdiff"
12
16
"github.com/hexops/gotextdiff/myers"
13
17
"github.com/hexops/gotextdiff/span"
@@ -29,6 +33,9 @@ func NewGci(settings *config.GciSettings) *goanalysis.Linter {
29
33
Name : gciName ,
30
34
Doc : goanalysis .TheOnlyanalyzerDoc ,
31
35
Run : goanalysis .DummyRun ,
36
+ Requires : []* analysis.Analyzer {
37
+ modinfo .Analyzer ,
38
+ },
32
39
}
33
40
34
41
var cfg * gcicfg.Config
@@ -47,7 +54,7 @@ func NewGci(settings *config.GciSettings) *goanalysis.Linter {
47
54
}
48
55
49
56
var err error
50
- cfg , err = rawCfg .Parse ()
57
+ cfg , err = YamlConfig { origin : rawCfg } .Parse ()
51
58
if err != nil {
52
59
internal .LinterLogger .Fatalf ("gci: configuration parsing: %v" , err )
53
60
}
@@ -62,6 +69,12 @@ func NewGci(settings *config.GciSettings) *goanalysis.Linter {
62
69
nil ,
63
70
).WithContextSetter (func (lintCtx * linter.Context ) {
64
71
analyzer .Run = func (pass * analysis.Pass ) (any , error ) {
72
+ var err error
73
+ cfg .Sections , err = hackSectionList (pass , cfg )
74
+ if err != nil {
75
+ return nil , err
76
+ }
77
+
65
78
issues , err := runGci (pass , lintCtx , cfg , & lock )
66
79
if err != nil {
67
80
return nil , err
@@ -111,6 +124,57 @@ func runGci(pass *analysis.Pass, lintCtx *linter.Context, cfg *gcicfg.Config, lo
111
124
return issues , nil
112
125
}
113
126
127
+ func getIssuedTextGci (settings * config.LintersSettings ) string {
128
+ text := "File is not `gci`-ed"
129
+
130
+ hasOptions := settings .Gci .SkipGenerated || len (settings .Gci .Sections ) > 0
131
+ if ! hasOptions {
132
+ return text
133
+ }
134
+
135
+ text += " with"
136
+
137
+ if settings .Gci .SkipGenerated {
138
+ text += " --skip-generated"
139
+ }
140
+
141
+ if len (settings .Gci .Sections ) > 0 {
142
+ for _ , sect := range settings .Gci .Sections {
143
+ text += " -s " + sect
144
+ }
145
+ }
146
+
147
+ if settings .Gci .CustomOrder {
148
+ text += " --custom-order"
149
+ }
150
+
151
+ return text
152
+ }
153
+
154
+ func hackSectionList (pass * analysis.Pass , cfg * gcicfg.Config ) (section.SectionList , error ) {
155
+ var sections section.SectionList
156
+
157
+ for _ , sect := range cfg .Sections {
158
+ // local module hack
159
+ if v , ok := sect .(* section.LocalModule ); ok {
160
+ info , err := modinfo .FindModuleFromPass (pass )
161
+ if err != nil {
162
+ return nil , err
163
+ }
164
+
165
+ if info .Path == "" {
166
+ continue
167
+ }
168
+
169
+ v .Path = info .Path
170
+ }
171
+
172
+ sections = append (sections , sect )
173
+ }
174
+
175
+ return sections , nil
176
+ }
177
+
114
178
// diffFormattedFilesToArray is a copy of gci.DiffFormattedFilesToArray without io.StdInGenerator.
115
179
// gci.DiffFormattedFilesToArray uses gci.processStdInAndGoFilesInPaths that uses io.StdInGenerator but stdin is not active on CI.
116
180
// https://github.com/daixiang0/gci/blob/6f5cb16718ba07f0342a58de9b830ec5a6d58790/pkg/gci/gci.go#L63-L75
@@ -130,29 +194,55 @@ func diffFormattedFilesToArray(paths []string, cfg gcicfg.Config, diffs *[]strin
130
194
})
131
195
}
132
196
133
- func getIssuedTextGci (settings * config.LintersSettings ) string {
134
- text := "File is not `gci`-ed"
197
+ // Code bellow this comment is borrowed and modified from gci.
198
+ // https://github.com/daixiang0/gci/blob/4725b0c101801e7449530eee2ddb0c72592e3405/pkg/config/config.go
199
+
200
+ var defaultOrder = map [string ]int {
201
+ section .StandardType : 0 ,
202
+ section .DefaultType : 1 ,
203
+ section .CustomType : 2 ,
204
+ section .BlankType : 3 ,
205
+ section .DotType : 4 ,
206
+ section .AliasType : 5 ,
207
+ section .LocalModuleType : 6 ,
208
+ }
135
209
136
- hasOptions := settings .Gci .SkipGenerated || len (settings .Gci .Sections ) > 0
137
- if ! hasOptions {
138
- return text
139
- }
210
+ type YamlConfig struct {
211
+ origin gcicfg.YamlConfig
212
+ }
140
213
141
- text += " with"
214
+ //nolint:gocritic // code borrowed from gci and modified to fix LocalModule section behavior.
215
+ func (g YamlConfig ) Parse () (* gcicfg.Config , error ) {
216
+ var err error
142
217
143
- if settings .Gci .SkipGenerated {
144
- text += " --skip-generated"
218
+ sections , err := section .Parse (g .origin .SectionStrings )
219
+ if err != nil {
220
+ return nil , err
145
221
}
146
222
147
- if len (settings .Gci .Sections ) > 0 {
148
- for _ , section := range settings .Gci .Sections {
149
- text += " -s " + section
150
- }
223
+ if sections == nil {
224
+ sections = section .DefaultSections ()
151
225
}
152
226
153
- if settings .Gci .CustomOrder {
154
- text += " --custom-order"
227
+ // if default order sorted sections
228
+ if ! g .origin .Cfg .CustomOrder {
229
+ sort .Slice (sections , func (i , j int ) bool {
230
+ sectionI , sectionJ := sections [i ].Type (), sections [j ].Type ()
231
+
232
+ if strings .Compare (sectionI , sectionJ ) == 0 {
233
+ return strings .Compare (sections [i ].String (), sections [j ].String ()) < 0
234
+ }
235
+ return defaultOrder [sectionI ] < defaultOrder [sectionJ ]
236
+ })
155
237
}
156
238
157
- return text
239
+ sectionSeparators , err := section .Parse (g .origin .SectionSeparatorStrings )
240
+ if err != nil {
241
+ return nil , err
242
+ }
243
+ if sectionSeparators == nil {
244
+ sectionSeparators = section .DefaultSectionSeparators ()
245
+ }
246
+
247
+ return & gcicfg.Config {BoolConfig : g .origin .Cfg , Sections : sections , SectionSeparators : sectionSeparators }, nil
158
248
}
0 commit comments