github.com/nozzle/golangci-lint@v1.49.0-nz3/pkg/golinters/goimports.go (about)

     1  package golinters
     2  
     3  import (
     4  	"sync"
     5  
     6  	goimportsAPI "github.com/golangci/gofmt/goimports"
     7  	"github.com/pkg/errors"
     8  	"golang.org/x/tools/go/analysis"
     9  	"golang.org/x/tools/imports"
    10  
    11  	"github.com/golangci/golangci-lint/pkg/config"
    12  	"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
    13  	"github.com/golangci/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  		"In addition to fixing imports, goimports also formats your code in the same style as gofmt.",
    31  		[]*analysis.Analyzer{analyzer},
    32  		nil,
    33  	).WithContextSetter(func(lintCtx *linter.Context) {
    34  		imports.LocalPrefix = settings.LocalPrefixes
    35  
    36  		analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
    37  			issues, err := runGoImports(lintCtx, pass)
    38  			if err != nil {
    39  				return nil, err
    40  			}
    41  
    42  			if len(issues) == 0 {
    43  				return nil, nil
    44  			}
    45  
    46  			mu.Lock()
    47  			resIssues = append(resIssues, issues...)
    48  			mu.Unlock()
    49  
    50  			return nil, nil
    51  		}
    52  	}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    53  		return resIssues
    54  	}).WithLoadMode(goanalysis.LoadModeSyntax)
    55  }
    56  
    57  func runGoImports(lintCtx *linter.Context, pass *analysis.Pass) ([]goanalysis.Issue, error) {
    58  	fileNames := getFileNames(pass)
    59  
    60  	var issues []goanalysis.Issue
    61  
    62  	for _, f := range fileNames {
    63  		diff, err := goimportsAPI.Run(f)
    64  		if err != nil { // TODO: skip
    65  			return nil, err
    66  		}
    67  		if diff == nil {
    68  			continue
    69  		}
    70  
    71  		is, err := extractIssuesFromPatch(string(diff), lintCtx, goimportsName)
    72  		if err != nil {
    73  			return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
    74  		}
    75  
    76  		for i := range is {
    77  			issues = append(issues, goanalysis.NewIssue(&is[i], pass))
    78  		}
    79  	}
    80  
    81  	return issues, nil
    82  }