github.com/chenfeining/golangci-lint@v1.0.2-0.20230730162517-14c6c67868df/pkg/golinters/goimports.go (about) 1 package golinters 2 3 import ( 4 "fmt" 5 "sync" 6 7 goimportsAPI "github.com/golangci/gofmt/goimports" 8 "golang.org/x/tools/go/analysis" 9 "golang.org/x/tools/imports" 10 11 "github.com/chenfeining/golangci-lint/pkg/config" 12 "github.com/chenfeining/golangci-lint/pkg/golinters/goanalysis" 13 "github.com/chenfeining/golangci-lint/pkg/lint/linter" 14 ) 15 16 const goimportsName = "goimports" 17 18 func NewGoimports(settings *config.GoImportsSettings) *goanalysis.Linter { 19 var mu sync.Mutex 20 var resIssues []goanalysis.Issue 21 22 analyzer := &analysis.Analyzer{ 23 Name: goimportsName, 24 Doc: goanalysis.TheOnlyanalyzerDoc, 25 Run: goanalysis.DummyRun, 26 } 27 28 return goanalysis.NewLinter( 29 goimportsName, 30 "Check import statements are formatted according to the 'goimport' command. "+ 31 "Reformat imports in autofix mode.", 32 []*analysis.Analyzer{analyzer}, 33 nil, 34 ).WithContextSetter(func(lintCtx *linter.Context) { 35 imports.LocalPrefix = settings.LocalPrefixes 36 37 analyzer.Run = func(pass *analysis.Pass) (any, error) { 38 issues, err := runGoImports(lintCtx, pass) 39 if err != nil { 40 return nil, err 41 } 42 43 if len(issues) == 0 { 44 return nil, nil 45 } 46 47 mu.Lock() 48 resIssues = append(resIssues, issues...) 49 mu.Unlock() 50 51 return nil, nil 52 } 53 }).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { 54 return resIssues 55 }).WithLoadMode(goanalysis.LoadModeSyntax) 56 } 57 58 func runGoImports(lintCtx *linter.Context, pass *analysis.Pass) ([]goanalysis.Issue, error) { 59 fileNames := getFileNames(pass) 60 61 var issues []goanalysis.Issue 62 63 for _, f := range fileNames { 64 diff, err := goimportsAPI.Run(f) 65 if err != nil { // TODO: skip 66 return nil, err 67 } 68 if diff == nil { 69 continue 70 } 71 72 is, err := extractIssuesFromPatch(string(diff), lintCtx, goimportsName) 73 if err != nil { 74 return nil, fmt.Errorf("can't extract issues from gofmt diff output %q: %w", string(diff), err) 75 } 76 77 for i := range is { 78 issues = append(issues, goanalysis.NewIssue(&is[i], pass)) 79 } 80 } 81 82 return issues, nil 83 }