@@ -4,31 +4,24 @@ import (
4
4
"context"
5
5
"errors"
6
6
"fmt"
7
- "go/build"
8
7
"go/token"
9
8
"io/ioutil"
10
9
"log"
11
10
"os"
12
- "os/exec"
13
11
"runtime"
14
12
"strings"
15
13
"time"
16
14
17
- "github.com/golangci/go-tools/ssa"
18
- "github.com/golangci/go-tools/ssa/ssautil"
19
15
"github.com/golangci/golangci-lint/pkg"
20
- "github.com/golangci/golangci-lint/pkg/astcache"
21
16
"github.com/golangci/golangci-lint/pkg/config"
22
- "github.com/golangci/golangci-lint/pkg/fsutils"
23
- "github.com/golangci/golangci-lint/pkg/golinters"
17
+ "github.com/golangci/golangci-lint/pkg/lint"
24
18
"github.com/golangci/golangci-lint/pkg/printers"
25
19
"github.com/golangci/golangci-lint/pkg/result"
26
20
"github.com/golangci/golangci-lint/pkg/result/processors"
27
21
"github.com/sirupsen/logrus"
28
22
"github.com/spf13/cobra"
29
23
"github.com/spf13/pflag"
30
24
"github.com/spf13/viper"
31
- "golang.org/x/tools/go/loader"
32
25
)
33
26
34
27
const (
@@ -126,170 +119,6 @@ func (e *Executor) initRun() {
126
119
e .parseConfig (runCmd )
127
120
}
128
121
129
- func isFullImportNeeded (linters []pkg.Linter ) bool {
130
- for _ , linter := range linters {
131
- lc := pkg .GetLinterConfig (linter .Name ())
132
- if lc .DoesFullImport {
133
- return true
134
- }
135
- }
136
-
137
- return false
138
- }
139
-
140
- func isSSAReprNeeded (linters []pkg.Linter ) bool {
141
- for _ , linter := range linters {
142
- lc := pkg .GetLinterConfig (linter .Name ())
143
- if lc .NeedsSSARepr {
144
- return true
145
- }
146
- }
147
-
148
- return false
149
- }
150
-
151
- func loadWholeAppIfNeeded (ctx context.Context , linters []pkg.Linter , cfg * config.Run , paths * fsutils.ProjectPaths ) (* loader.Program , * loader.Config , error ) {
152
- if ! isFullImportNeeded (linters ) {
153
- return nil , nil , nil
154
- }
155
-
156
- startedAt := time .Now ()
157
- defer func () {
158
- logrus .Infof ("Program loading took %s" , time .Since (startedAt ))
159
- }()
160
-
161
- bctx := build .Default
162
- bctx .BuildTags = append (bctx .BuildTags , cfg .BuildTags ... )
163
- loadcfg := & loader.Config {
164
- Build : & bctx ,
165
- AllowErrors : true , // Try to analyze event partially
166
- }
167
- rest , err := loadcfg .FromArgs (paths .MixedPaths (), cfg .AnalyzeTests )
168
- if err != nil {
169
- return nil , nil , fmt .Errorf ("can't parepare load config with paths: %s" , err )
170
- }
171
- if len (rest ) > 0 {
172
- return nil , nil , fmt .Errorf ("unhandled loading paths: %v" , rest )
173
- }
174
-
175
- prog , err := loadcfg .Load ()
176
- if err != nil {
177
- return nil , nil , fmt .Errorf ("can't load paths: %s" , err )
178
- }
179
-
180
- return prog , loadcfg , nil
181
- }
182
-
183
- func buildSSAProgram (ctx context.Context , lprog * loader.Program ) * ssa.Program {
184
- startedAt := time .Now ()
185
- defer func () {
186
- logrus .Infof ("SSA repr building took %s" , time .Since (startedAt ))
187
- }()
188
-
189
- ssaProg := ssautil .CreateProgram (lprog , ssa .GlobalDebug )
190
- ssaProg .Build ()
191
- return ssaProg
192
- }
193
-
194
- func discoverGoRoot () (string , error ) {
195
- goroot := os .Getenv ("GOROOT" )
196
- if goroot != "" {
197
- return goroot , nil
198
- }
199
-
200
- output , err := exec .Command ("go" , "env" , "GOROOT" ).Output ()
201
- if err != nil {
202
- return "" , fmt .Errorf ("can't execute go env GOROOT: %s" , err )
203
- }
204
-
205
- return strings .TrimSpace (string (output )), nil
206
- }
207
-
208
- // separateNotCompilingPackages moves not compiling packages into separate slices:
209
- // a lot of linters crash on such packages. Leave them only for those linters
210
- // which can work with them.
211
- func separateNotCompilingPackages (lintCtx * golinters.Context ) {
212
- prog := lintCtx .Program
213
-
214
- if prog .Created != nil {
215
- compilingCreated := make ([]* loader.PackageInfo , 0 , len (prog .Created ))
216
- for _ , info := range prog .Created {
217
- if len (info .Errors ) != 0 {
218
- lintCtx .NotCompilingPackages = append (lintCtx .NotCompilingPackages , info )
219
- } else {
220
- compilingCreated = append (compilingCreated , info )
221
- }
222
- }
223
- prog .Created = compilingCreated
224
- }
225
-
226
- if prog .Imported != nil {
227
- for k , info := range prog .Imported {
228
- if len (info .Errors ) != 0 {
229
- lintCtx .NotCompilingPackages = append (lintCtx .NotCompilingPackages , info )
230
- delete (prog .Imported , k )
231
- }
232
- }
233
- }
234
- }
235
-
236
- func buildLintCtx (ctx context.Context , linters []pkg.Linter , cfg * config.Config ) (* golinters.Context , error ) {
237
- // Set GOROOT to have working cross-compilation: cross-compiled binaries
238
- // have invalid GOROOT. XXX: can't use runtime.GOROOT().
239
- goroot , err := discoverGoRoot ()
240
- if err != nil {
241
- return nil , fmt .Errorf ("can't discover GOROOT: %s" , err )
242
- }
243
- os .Setenv ("GOROOT" , goroot )
244
- build .Default .GOROOT = goroot
245
- logrus .Infof ("set GOROOT=%q" , goroot )
246
-
247
- args := cfg .Run .Args
248
- if len (args ) == 0 {
249
- args = []string {"./..." }
250
- }
251
-
252
- paths , err := fsutils .GetPathsForAnalysis (ctx , args , cfg .Run .AnalyzeTests )
253
- if err != nil {
254
- return nil , err
255
- }
256
-
257
- prog , loaderConfig , err := loadWholeAppIfNeeded (ctx , linters , & cfg .Run , paths )
258
- if err != nil {
259
- return nil , err
260
- }
261
-
262
- var ssaProg * ssa.Program
263
- if prog != nil && isSSAReprNeeded (linters ) {
264
- ssaProg = buildSSAProgram (ctx , prog )
265
- }
266
-
267
- var astCache * astcache.Cache
268
- if prog != nil {
269
- astCache , err = astcache .LoadFromProgram (prog )
270
- if err != nil {
271
- return nil , err
272
- }
273
- } else {
274
- astCache = astcache .LoadFromFiles (paths .Files )
275
- }
276
-
277
- ret := & golinters.Context {
278
- Paths : paths ,
279
- Cfg : cfg ,
280
- Program : prog ,
281
- SSAProgram : ssaProg ,
282
- LoaderConfig : loaderConfig ,
283
- ASTCache : astCache ,
284
- }
285
-
286
- if prog != nil {
287
- separateNotCompilingPackages (ret )
288
- }
289
-
290
- return ret , nil
291
- }
292
-
293
122
func (e * Executor ) runAnalysis (ctx context.Context , args []string ) (<- chan result.Issue , error ) {
294
123
e .cfg .Run .Args = args
295
124
@@ -298,7 +127,11 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
298
127
return nil , err
299
128
}
300
129
301
- lintCtx , err := buildLintCtx (ctx , linters , e .cfg )
130
+ ctxLinters := make ([]lint.LinterConfig , 0 , len (linters ))
131
+ for _ , lc := range linters {
132
+ ctxLinters = append (ctxLinters , lint .LinterConfig (lc ))
133
+ }
134
+ lintCtx , err := lint .BuildContext (ctx , ctxLinters , e .cfg )
302
135
if err != nil {
303
136
return nil , err
304
137
}
@@ -315,7 +148,7 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
315
148
if lintCtx .Program != nil {
316
149
fset = lintCtx .Program .Fset
317
150
}
318
- runner := pkg .SimpleRunner {
151
+ runner := lint .SimpleRunner {
319
152
Processors : []processors.Processor {
320
153
processors .NewPathPrettifier (), // must be before diff processor at least
321
154
processors .NewExclude (excludeTotalPattern ),
@@ -329,7 +162,11 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
329
162
},
330
163
}
331
164
332
- return runner .Run (ctx , linters , lintCtx ), nil
165
+ runLinters := make ([]lint.RunnerLinterConfig , 0 , len (linters ))
166
+ for _ , lc := range linters {
167
+ runLinters = append (runLinters , lint .RunnerLinterConfig (lc ))
168
+ }
169
+ return runner .Run (ctx , runLinters , lintCtx ), nil
333
170
}
334
171
335
172
func setOutputToDevNull () (savedStdout , savedStderr * os.File ) {
@@ -364,7 +201,7 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
364
201
p = printers .NewText (e .cfg .Output .PrintIssuedLine ,
365
202
e .cfg .Output .Format == config .OutFormatColoredLineNumber , e .cfg .Output .PrintLinterName )
366
203
}
367
- gotAnyIssues , err := p .Print (issues )
204
+ gotAnyIssues , err := p .Print (ctx , issues )
368
205
if err != nil {
369
206
return fmt .Errorf ("can't print %d issues: %s" , len (issues ), err )
370
207
}
0 commit comments