diff --git a/go.mod b/go.mod index e692851cedd2..cfd5ffc6c35a 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/ckaznocha/intrange v0.3.1 github.com/curioswitch/go-reassign v0.3.0 github.com/daixiang0/gci v0.13.7 - github.com/denis-tingaikin/go-header v0.5.0 + github.com/denis-tingaikin/go-header v1.0.0 github.com/fatih/color v1.18.0 github.com/firefart/nonamedreturns v1.0.6 github.com/fzipp/gocyclo v0.6.0 diff --git a/go.sum b/go.sum index 44daa399d838..3d1e142dfd0c 100644 --- a/go.sum +++ b/go.sum @@ -150,8 +150,8 @@ github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8= -github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY= +github.com/denis-tingaikin/go-header v1.0.0 h1:QIwZWb3jLC6pOp9NEFldiD8raqRmCE/n0VUdZKW32x8= +github.com/denis-tingaikin/go-header v1.0.0/go.mod h1:NT3qKwqsXQYp8WHVgkwxL49qB5jsRmdr9dGQCDfpmZ0= github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= diff --git a/pkg/golinters/goheader/goheader.go b/pkg/golinters/goheader/goheader.go index 0634dbd4288f..8c57aeb2e5e4 100644 --- a/pkg/golinters/goheader/goheader.go +++ b/pkg/golinters/goheader/goheader.go @@ -1,7 +1,6 @@ package goheader import ( - "go/token" "strings" goheader "github.com/denis-tingaikin/go-header" @@ -9,118 +8,28 @@ import ( "github.com/golangci/golangci-lint/v2/pkg/config" "github.com/golangci/golangci-lint/v2/pkg/goanalysis" + "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" ) const linterName = "goheader" func New(settings *config.GoHeaderSettings, replacer *strings.Replacer) *goanalysis.Linter { - conf := &goheader.Configuration{} + conf := &goheader.Config{} if settings != nil { - conf = &goheader.Configuration{ + conf = &goheader.Config{ Values: settings.Values, Template: settings.Template, TemplatePath: replacer.Replace(settings.TemplatePath), } } - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Check if file header matches to pattern", - Run: func(pass *analysis.Pass) (any, error) { - err := runGoHeader(pass, conf) - if err != nil { - return nil, err - } - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGoHeader(pass *analysis.Pass, conf *goheader.Configuration) error { - if conf.TemplatePath == "" && conf.Template == "" { - // User did not pass template, so then do not run go-header linter - return nil - } - - template, err := conf.GetTemplate() - if err != nil { - return err - } - - values, err := conf.GetValues() - if err != nil { - return err + var goheaderSettings goheader.Settings + if err := conf.FillSettings(&goheaderSettings); err != nil { + internal.LinterLogger.Fatalf("%s: invalid toolchain pattern: %s", linterName, err.Error()) } - - a := goheader.New(goheader.WithTemplate(template), goheader.WithValues(values)) - - for _, file := range pass.Files { - position, isGoFile := goanalysis.GetGoFilePosition(pass, file) - if !isGoFile { - continue - } - - issue := a.Analyze(&goheader.Target{File: file, Path: position.Filename}) - if issue == nil { - continue - } - - f := pass.Fset.File(file.Pos()) - - commentLine := 1 - var offset int - - // Inspired by https://github.com/denis-tingaikin/go-header/blob/4c75a6a2332f025705325d6c71fff4616aedf48f/analyzer.go#L85-L92 - if len(file.Comments) > 0 && file.Comments[0].Pos() < file.Package { - if !strings.HasPrefix(file.Comments[0].List[0].Text, "/*") { - // When the comment is "//" there is a one character offset. - offset = 1 - } - commentLine = goanalysis.GetFilePositionFor(pass.Fset, file.Comments[0].Pos()).Line - } - - // Skip issues related to build directives. - // https://github.com/denis-tingaikin/go-header/issues/18 - if issue.Location().Position-offset < 0 { - continue - } - - diag := analysis.Diagnostic{ - Pos: f.LineStart(issue.Location().Line+1) + token.Pos(issue.Location().Position-offset), // The position of the first divergence. - Message: issue.Message(), - } - - if fix := issue.Fix(); fix != nil { - current := len(fix.Actual) - for _, s := range fix.Actual { - current += len(s) - } - - start := f.LineStart(commentLine) - - end := start + token.Pos(current) - - header := strings.Join(fix.Expected, "\n") + "\n" - - // Adds an extra line between the package and the header. - if end == file.Package { - header += "\n" - } - - diag.SuggestedFixes = []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: start, - End: end, - NewText: []byte(header), - }}, - }} - } - - pass.Report(diag) - } - - return nil + return goanalysis.NewLinter( + linterName, + "Checks if file header matches to pattern", + []*analysis.Analyzer{goheader.New(&goheaderSettings)}, + nil, + ).WithLoadMode(goanalysis.LoadModeSyntax) } diff --git a/pkg/golinters/goheader/testdata/fix/in/goheader_3.go b/pkg/golinters/goheader/testdata/fix/in/goheader_3.go index cf440a315327..b6ab5e27d8da 100644 --- a/pkg/golinters/goheader/testdata/fix/in/goheader_3.go +++ b/pkg/golinters/goheader/testdata/fix/in/goheader_3.go @@ -1,8 +1,8 @@ /* -Copyright 1999 The Awesome - -Use of this source code is governed by LICENSE -*/ + * Copyright 1999 The Awesome + * + * Use of this source code is governed by LICENSE + */ //golangcitest:args -Egoheader //golangcitest:expected_exitcode 0 diff --git a/pkg/golinters/goheader/testdata/fix/out/goheader_2.go b/pkg/golinters/goheader/testdata/fix/out/goheader_2.go index 4084bdab2090..2fc7637b7ae1 100644 --- a/pkg/golinters/goheader/testdata/fix/out/goheader_2.go +++ b/pkg/golinters/goheader/testdata/fix/out/goheader_2.go @@ -1,6 +1,8 @@ -/* Copyright 2024 The Awesome Project Authors +/* +Copyright 2024 The Awesome Project Authors -Use of this source code is governed by LICENSE */ +Use of this source code is governed by LICENSE +*/ //golangcitest:args -Egoheader //golangcitest:expected_exitcode 0 diff --git a/pkg/golinters/goheader/testdata/fix/out/goheader_3.go b/pkg/golinters/goheader/testdata/fix/out/goheader_3.go index 2fc7637b7ae1..e6f1c010b2b6 100644 --- a/pkg/golinters/goheader/testdata/fix/out/goheader_3.go +++ b/pkg/golinters/goheader/testdata/fix/out/goheader_3.go @@ -1,8 +1,8 @@ /* -Copyright 2024 The Awesome Project Authors - -Use of this source code is governed by LICENSE -*/ + * Copyright 2024 The Awesome Project Authors + * + * Use of this source code is governed by LICENSE + */ //golangcitest:args -Egoheader //golangcitest:expected_exitcode 0 diff --git a/pkg/golinters/goheader/testdata/fix/out/goheader_4.go b/pkg/golinters/goheader/testdata/fix/out/goheader_4.go index d0e6f8a8ef16..2fc7637b7ae1 100644 --- a/pkg/golinters/goheader/testdata/fix/out/goheader_4.go +++ b/pkg/golinters/goheader/testdata/fix/out/goheader_4.go @@ -1,7 +1,7 @@ /* - Copyright 2024 The Awesome Project Authors +Copyright 2024 The Awesome Project Authors - Use of this source code is governed by LICENSE +Use of this source code is governed by LICENSE */ //golangcitest:args -Egoheader diff --git a/pkg/golinters/goheader/testdata/goheader-fix.yml b/pkg/golinters/goheader/testdata/goheader-fix.yml index 183c4076c17e..432d47b84933 100644 --- a/pkg/golinters/goheader/testdata/goheader-fix.yml +++ b/pkg/golinters/goheader/testdata/goheader-fix.yml @@ -7,6 +7,6 @@ linters: const: AUTHOR: The Awesome Project Authors template: |- - Copyright 2024 {{ AUTHOR }} - + Copyright 2024 {{ .AUTHOR }} + Use of this source code is governed by LICENSE diff --git a/pkg/golinters/goheader/testdata/goheader.yml b/pkg/golinters/goheader/testdata/goheader.yml index cb10cdf025d8..8677b8ca0a98 100644 --- a/pkg/golinters/goheader/testdata/goheader.yml +++ b/pkg/golinters/goheader/testdata/goheader.yml @@ -3,7 +3,7 @@ version: "2" linters: settings: goheader: - template: MY {{title}} + template: MY {{.title}}. values: const: - title: TITLE. + title: TITLE diff --git a/pkg/golinters/goheader/testdata/goheader_bad.go b/pkg/golinters/goheader/testdata/goheader_bad.go index 73d7b8a77bca..4a62f530069d 100644 --- a/pkg/golinters/goheader/testdata/goheader_bad.go +++ b/pkg/golinters/goheader/testdata/goheader_bad.go @@ -1,5 +1,6 @@ -/*MY TITLE!*/ // want `Expected:TITLE\., Actual: TITLE!` +/*oops!*/ // want `template doesn't match` //golangcitest:args -Egoheader //golangcitest:config_path testdata/goheader.yml +//golangcitest:expected_exitcode 1 package testdata diff --git a/pkg/golinters/goheader/testdata/goheader_cgo.go b/pkg/golinters/goheader/testdata/goheader_cgo.go index 7b668fd34f24..2dbac9d885cf 100644 --- a/pkg/golinters/goheader/testdata/goheader_cgo.go +++ b/pkg/golinters/goheader/testdata/goheader_cgo.go @@ -1,11 +1,10 @@ //go:build ignore -// TODO(ldez) the linter doesn't support cgo. - -/*MY TITLE!*/ // want `Expected:TITLE\., Actual: TITLE!` +/*my template*/ // want `template doesn't match` //golangcitest:args -Egoheader //golangcitest:config_path testdata/goheader.yml +//golangcitest:expected_exitcode 1 package testdata /*