github.com/vanstinator/golangci-lint@v0.0.0-20240223191551-cc572f00d9d1/pkg/golinters/promlinter.go (about)

     1  package golinters
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	"github.com/yeya24/promlinter"
     8  	"golang.org/x/tools/go/analysis"
     9  
    10  	"github.com/vanstinator/golangci-lint/pkg/config"
    11  	"github.com/vanstinator/golangci-lint/pkg/golinters/goanalysis"
    12  	"github.com/vanstinator/golangci-lint/pkg/lint/linter"
    13  	"github.com/vanstinator/golangci-lint/pkg/result"
    14  )
    15  
    16  const promlinterName = "promlinter"
    17  
    18  func NewPromlinter(settings *config.PromlinterSettings) *goanalysis.Linter {
    19  	var mu sync.Mutex
    20  	var resIssues []goanalysis.Issue
    21  
    22  	var promSettings promlinter.Setting
    23  	if settings != nil {
    24  		promSettings = promlinter.Setting{
    25  			Strict:            settings.Strict,
    26  			DisabledLintFuncs: settings.DisabledLinters,
    27  		}
    28  	}
    29  
    30  	analyzer := &analysis.Analyzer{
    31  		Name: promlinterName,
    32  		Doc:  goanalysis.TheOnlyanalyzerDoc,
    33  		Run: func(pass *analysis.Pass) (any, error) {
    34  			issues := runPromLinter(pass, promSettings)
    35  
    36  			if len(issues) == 0 {
    37  				return nil, nil
    38  			}
    39  
    40  			mu.Lock()
    41  			resIssues = append(resIssues, issues...)
    42  			mu.Unlock()
    43  
    44  			return nil, nil
    45  		},
    46  	}
    47  
    48  	return goanalysis.NewLinter(
    49  		promlinterName,
    50  		"Check Prometheus metrics naming via promlint",
    51  		[]*analysis.Analyzer{analyzer},
    52  		nil,
    53  	).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    54  		return resIssues
    55  	}).WithLoadMode(goanalysis.LoadModeSyntax)
    56  }
    57  
    58  func runPromLinter(pass *analysis.Pass, promSettings promlinter.Setting) []goanalysis.Issue {
    59  	lintIssues := promlinter.RunLint(pass.Fset, pass.Files, promSettings)
    60  
    61  	if len(lintIssues) == 0 {
    62  		return nil
    63  	}
    64  
    65  	issues := make([]goanalysis.Issue, len(lintIssues))
    66  	for k, i := range lintIssues {
    67  		issue := result.Issue{
    68  			Pos:        i.Pos,
    69  			Text:       fmt.Sprintf("Metric: %s Error: %s", i.Metric, i.Text),
    70  			FromLinter: promlinterName,
    71  		}
    72  
    73  		issues[k] = goanalysis.NewIssue(&issue, pass)
    74  	}
    75  
    76  	return issues
    77  }