github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/pkg/golinters/gofmt.go (about)

     1  package golinters
     2  
     3  import (
     4  	"sync"
     5  
     6  	gofmtAPI "github.com/golangci/gofmt/gofmt"
     7  	"github.com/pkg/errors"
     8  	"golang.org/x/tools/go/analysis"
     9  
    10  	"github.com/elek/golangci-lint/pkg/golinters/goanalysis"
    11  	"github.com/elek/golangci-lint/pkg/lint/linter"
    12  )
    13  
    14  const gofmtName = "gofmt"
    15  
    16  func NewGofmt() *goanalysis.Linter {
    17  	var mu sync.Mutex
    18  	var resIssues []goanalysis.Issue
    19  
    20  	analyzer := &analysis.Analyzer{
    21  		Name: gofmtName,
    22  		Doc:  goanalysis.TheOnlyanalyzerDoc,
    23  	}
    24  	return goanalysis.NewLinter(
    25  		gofmtName,
    26  		"Gofmt checks whether code was gofmt-ed. By default "+
    27  			"this tool runs with -s option to check for code simplification",
    28  		[]*analysis.Analyzer{analyzer},
    29  		nil,
    30  	).WithContextSetter(func(lintCtx *linter.Context) {
    31  		analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
    32  			var fileNames []string
    33  			for _, f := range pass.Files {
    34  				pos := pass.Fset.PositionFor(f.Pos(), false)
    35  				fileNames = append(fileNames, pos.Filename)
    36  			}
    37  
    38  			var issues []goanalysis.Issue
    39  
    40  			for _, f := range fileNames {
    41  				diff, err := gofmtAPI.Run(f, lintCtx.Settings().Gofmt.Simplify)
    42  				if err != nil { // TODO: skip
    43  					return nil, err
    44  				}
    45  				if diff == nil {
    46  					continue
    47  				}
    48  
    49  				is, err := extractIssuesFromPatch(string(diff), lintCtx.Log, lintCtx, gofmtName)
    50  				if err != nil {
    51  					return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
    52  				}
    53  
    54  				for i := range is {
    55  					issues = append(issues, goanalysis.NewIssue(&is[i], pass))
    56  				}
    57  			}
    58  
    59  			if len(issues) == 0 {
    60  				return nil, nil
    61  			}
    62  
    63  			mu.Lock()
    64  			resIssues = append(resIssues, issues...)
    65  			mu.Unlock()
    66  
    67  			return nil, nil
    68  		}
    69  	}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    70  		return resIssues
    71  	}).WithLoadMode(goanalysis.LoadModeSyntax)
    72  }