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

     1  package golinters
     2  
     3  import (
     4  	"go/token"
     5  	"sync"
     6  
     7  	goheader "github.com/denis-tingajkin/go-header"
     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  	"github.com/elek/golangci-lint/pkg/result"
    13  )
    14  
    15  const goHeaderName = "goheader"
    16  
    17  func NewGoHeader() *goanalysis.Linter {
    18  	var mu sync.Mutex
    19  	var issues []goanalysis.Issue
    20  
    21  	analyzer := &analysis.Analyzer{
    22  		Name: goHeaderName,
    23  		Doc:  goanalysis.TheOnlyanalyzerDoc,
    24  	}
    25  	return goanalysis.NewLinter(
    26  		goHeaderName,
    27  		"Checks is file header matches to pattern",
    28  		[]*analysis.Analyzer{analyzer},
    29  		nil,
    30  	).WithContextSetter(func(lintCtx *linter.Context) {
    31  		cfg := lintCtx.Cfg.LintersSettings.Goheader
    32  		c := &goheader.Configuration{
    33  			Values:       cfg.Values,
    34  			Template:     cfg.Template,
    35  			TemplatePath: cfg.TemplatePath,
    36  		}
    37  		analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
    38  			if c.TemplatePath == "" && c.Template == "" {
    39  				// User did not pass template, so then do not run go-header linter
    40  				return nil, nil
    41  			}
    42  			template, err := c.GetTemplate()
    43  			if err != nil {
    44  				return nil, err
    45  			}
    46  			values, err := c.GetValues()
    47  			if err != nil {
    48  				return nil, err
    49  			}
    50  			a := goheader.New(goheader.WithTemplate(template), goheader.WithValues(values))
    51  			var res []goanalysis.Issue
    52  			for _, file := range pass.Files {
    53  				path := pass.Fset.Position(file.Pos()).Filename
    54  				i := a.Analyze(&goheader.Target{
    55  					File: file,
    56  					Path: path,
    57  				})
    58  				if i == nil {
    59  					continue
    60  				}
    61  				issue := result.Issue{
    62  					Pos: token.Position{
    63  						Line:     i.Location().Line + 1,
    64  						Column:   i.Location().Position,
    65  						Filename: path,
    66  					},
    67  					Text:       i.Message(),
    68  					FromLinter: goHeaderName,
    69  				}
    70  				res = append(res, goanalysis.NewIssue(&issue, pass))
    71  			}
    72  			if len(res) == 0 {
    73  				return nil, nil
    74  			}
    75  
    76  			mu.Lock()
    77  			issues = append(issues, res...)
    78  			mu.Unlock()
    79  
    80  			return nil, nil
    81  		}
    82  	}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    83  		return issues
    84  	}).WithLoadMode(goanalysis.LoadModeSyntax)
    85  }