Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gomoddirectives linter. #1817

Merged
merged 5 commits into from Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions .golangci.example.yml
Expand Up @@ -449,6 +449,16 @@ linters-settings:
servingv1: knative.dev/serving/pkg/apis/serving/v1
# using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package
autoscalingv1alpha1: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
gomoddirectives:
# Allow local `replace` directives. Default is false.
replace-local: false
# List of allowed `replace` directives. Default is empty.
replace-allow-list:
ldez marked this conversation as resolved.
Show resolved Hide resolved
- launchpad.net/gocheck
ldez marked this conversation as resolved.
Show resolved Hide resolved
# Allow to not explain why the version has been retracted in the `retract` directives. Default is false.
retract-allow-no-explanation: false
# Forbid the use of the `exclude` directives. Default is false.
exclude-forbidden: false
ldez marked this conversation as resolved.
Show resolved Hide resolved

# The custom section can be used to define linter plugins to be loaded at runtime. See README doc
# for more info.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -41,6 +41,7 @@ require (
github.com/kulti/thelper v0.4.0
github.com/kunwardeep/paralleltest v1.0.2
github.com/kyoh86/exportloopref v0.1.8
github.com/ldez/gomoddirectives v0.2.1
github.com/maratori/testpackage v1.0.1
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // v1.0
github.com/mattn/go-colorable v0.1.8
Expand Down
5 changes: 4 additions & 1 deletion go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions pkg/config/config.go
Expand Up @@ -276,6 +276,7 @@ type LintersSettings struct {
Predeclared PredeclaredSettings
Cyclop Cyclop
ImportAs ImportAsSettings
GoModDirectives GoModDirectivesSettings

Custom map[string]CustomLinterSettings
}
Expand Down Expand Up @@ -464,6 +465,13 @@ type Cyclop struct {

type ImportAsSettings map[string]string

type GoModDirectivesSettings struct {
ReplaceAllowList []string `mapstructure:"replace-allow-list"`
ReplaceLocal bool `mapstructure:"replace-local"`
ExcludeForbidden bool `mapstructure:"exclude-forbidden"`
RetractAllowNoExplanation bool `mapstructure:"retract-allow-no-explanation"`
}

var defaultLintersSettings = LintersSettings{
Lll: LllSettings{
LineLength: 120,
Expand Down
64 changes: 64 additions & 0 deletions pkg/golinters/gomoddirectives.go
@@ -0,0 +1,64 @@
package golinters

import (
"sync"

"github.com/ldez/gomoddirectives"
"golang.org/x/tools/go/analysis"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/result"
)

const goModDirectivesName = "gomoddirectives"

// NewGoModDirectives returns a new gomoddirectives linter.
func NewGoModDirectives(settings *config.GoModDirectivesSettings) *goanalysis.Linter {
var issues []goanalysis.Issue
var once sync.Once

var opts gomoddirectives.Options
if settings != nil {
opts.ReplaceAllowLocal = settings.ReplaceLocal
opts.ReplaceAllowList = settings.ReplaceAllowList
opts.RetractAllowNoExplanation = settings.RetractAllowNoExplanation
opts.ExcludeForbidden = settings.ExcludeForbidden
ldez marked this conversation as resolved.
Show resolved Hide resolved
}

analyzer := &analysis.Analyzer{
Name: goanalysis.TheOnlyAnalyzerName,
Doc: goanalysis.TheOnlyanalyzerDoc,
}

return goanalysis.NewLinter(
goModDirectivesName,
"Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.",
[]*analysis.Analyzer{analyzer},
nil,
).WithContextSetter(func(lintCtx *linter.Context) {
analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
once.Do(func() {
results, err := gomoddirectives.Analyze(opts)
if err != nil {
lintCtx.Log.Warnf("running %s failed: %s: "+
"if you are not using go modules it is suggested to disable this linter", goModDirectivesName, err)
return
}

for _, p := range results {
issues = append(issues, goanalysis.NewIssue(&result.Issue{
FromLinter: goModDirectivesName,
Pos: p.Start,
Text: p.Reason,
}, pass))
}
})

return nil, nil
}
}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
return issues
}).WithLoadMode(goanalysis.LoadModeSyntax)
}
6 changes: 6 additions & 0 deletions pkg/lint/lintersdb/manager.go
Expand Up @@ -100,6 +100,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
var reviveCfg *config.ReviveSettings
var cyclopCfg *config.Cyclop
var importAsCfg *config.ImportAsSettings
var goModDirectivesCfg *config.GoModDirectivesSettings
if m.cfg != nil {
govetCfg = &m.cfg.LintersSettings.Govet
testpackageCfg = &m.cfg.LintersSettings.Testpackage
Expand All @@ -112,6 +113,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
reviveCfg = &m.cfg.LintersSettings.Revive
cyclopCfg = &m.cfg.LintersSettings.Cyclop
importAsCfg = &m.cfg.LintersSettings.ImportAs
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
}
const megacheckName = "megacheck"
lcs := []*linter.Config{
Expand Down Expand Up @@ -394,6 +396,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis().
WithURL("https://github.com/gostaticanalysis/forcetypeassert"),
linter.NewConfig(golinters.NewGoModDirectives(goModDirectivesCfg)).
WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis().
WithURL("https://github.com/ldez/gomoddirectives"),

// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
linter.NewConfig(golinters.NewNoLintLint()).
Expand Down
4 changes: 4 additions & 0 deletions pkg/result/processors/autogenerated_exclude.go
Expand Up @@ -53,6 +53,10 @@ func (p *AutogeneratedExclude) shouldPassIssue(i *result.Issue) (bool, error) {
return true, nil
}

if filepath.Base(i.FilePath()) == "go.mod" {
return true, nil
}

if isSpecialAutogeneratedFile(i.FilePath()) {
return false, nil
}
Expand Down