github.com/nozzle/golangci-lint@v1.49.0-nz3/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/golangci/golangci-lint/pkg/config"
    11  	"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
    12  	"github.com/golangci/golangci-lint/pkg/lint/linter"
    13  )
    14  
    15  const gofmtName = "gofmt"
    16  
    17  func NewGofmt(settings *config.GoFmtSettings) *goanalysis.Linter {
    18  	var mu sync.Mutex
    19  	var resIssues []goanalysis.Issue
    20  
    21  	analyzer := &analysis.Analyzer{
    22  		Name: gofmtName,
    23  		Doc:  goanalysis.TheOnlyanalyzerDoc,
    24  		Run:  goanalysis.DummyRun,
    25  	}
    26  
    27  	return goanalysis.NewLinter(
    28  		gofmtName,
    29  		"Gofmt checks whether code was gofmt-ed. By default "+
    30  			"this tool runs with -s option to check for code simplification",
    31  		[]*analysis.Analyzer{analyzer},
    32  		nil,
    33  	).WithContextSetter(func(lintCtx *linter.Context) {
    34  		analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
    35  			issues, err := runGofmt(lintCtx, pass, settings)
    36  			if err != nil {
    37  				return nil, err
    38  			}
    39  
    40  			if len(issues) == 0 {
    41  				return nil, nil
    42  			}
    43  
    44  			mu.Lock()
    45  			resIssues = append(resIssues, issues...)
    46  			mu.Unlock()
    47  
    48  			return nil, nil
    49  		}
    50  	}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    51  		return resIssues
    52  	}).WithLoadMode(goanalysis.LoadModeSyntax)
    53  }
    54  
    55  func runGofmt(lintCtx *linter.Context, pass *analysis.Pass, settings *config.GoFmtSettings) ([]goanalysis.Issue, error) {
    56  	fileNames := getFileNames(pass)
    57  
    58  	var rewriteRules []gofmtAPI.RewriteRule
    59  	for _, rule := range settings.RewriteRules {
    60  		rewriteRules = append(rewriteRules, gofmtAPI.RewriteRule(rule))
    61  	}
    62  
    63  	var issues []goanalysis.Issue
    64  
    65  	for _, f := range fileNames {
    66  		diff, err := gofmtAPI.RunRewrite(f, settings.Simplify, rewriteRules)
    67  		if err != nil { // TODO: skip
    68  			return nil, err
    69  		}
    70  		if diff == nil {
    71  			continue
    72  		}
    73  
    74  		is, err := extractIssuesFromPatch(string(diff), lintCtx, gofmtName)
    75  		if err != nil {
    76  			return nil, errors.Wrapf(err, "can't extract issues from gofmt diff output %q", string(diff))
    77  		}
    78  
    79  		for i := range is {
    80  			issues = append(issues, goanalysis.NewIssue(&is[i], pass))
    81  		}
    82  	}
    83  
    84  	return issues, nil
    85  }