@@ -4,31 +4,24 @@ import (
44 "context"
55 "errors"
66 "fmt"
7- "go/build"
87 "go/token"
98 "io/ioutil"
109 "log"
1110 "os"
12- "os/exec"
1311 "runtime"
1412 "strings"
1513 "time"
1614
17- "github.com/golangci/go-tools/ssa"
18- "github.com/golangci/go-tools/ssa/ssautil"
1915 "github.com/golangci/golangci-lint/pkg"
20- "github.com/golangci/golangci-lint/pkg/astcache"
2116 "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"
2418 "github.com/golangci/golangci-lint/pkg/printers"
2519 "github.com/golangci/golangci-lint/pkg/result"
2620 "github.com/golangci/golangci-lint/pkg/result/processors"
2721 "github.com/sirupsen/logrus"
2822 "github.com/spf13/cobra"
2923 "github.com/spf13/pflag"
3024 "github.com/spf13/viper"
31- "golang.org/x/tools/go/loader"
3225)
3326
3427const (
@@ -126,170 +119,6 @@ func (e *Executor) initRun() {
126119 e .parseConfig (runCmd )
127120}
128121
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-
293122func (e * Executor ) runAnalysis (ctx context.Context , args []string ) (<- chan result.Issue , error ) {
294123 e .cfg .Run .Args = args
295124
@@ -298,7 +127,11 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
298127 return nil , err
299128 }
300129
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 )
302135 if err != nil {
303136 return nil , err
304137 }
@@ -315,7 +148,7 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
315148 if lintCtx .Program != nil {
316149 fset = lintCtx .Program .Fset
317150 }
318- runner := pkg .SimpleRunner {
151+ runner := lint .SimpleRunner {
319152 Processors : []processors.Processor {
320153 processors .NewPathPrettifier (), // must be before diff processor at least
321154 processors .NewExclude (excludeTotalPattern ),
@@ -329,7 +162,11 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
329162 },
330163 }
331164
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
333170}
334171
335172func setOutputToDevNull () (savedStdout , savedStderr * os.File ) {
@@ -364,7 +201,7 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
364201 p = printers .NewText (e .cfg .Output .PrintIssuedLine ,
365202 e .cfg .Output .Format == config .OutFormatColoredLineNumber , e .cfg .Output .PrintLinterName )
366203 }
367- gotAnyIssues , err := p .Print (issues )
204+ gotAnyIssues , err := p .Print (ctx , issues )
368205 if err != nil {
369206 return fmt .Errorf ("can't print %d issues: %s" , len (issues ), err )
370207 }
0 commit comments