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

depguard: updates configuration #2467

Merged
merged 15 commits into from
Jan 9, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .golangci.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -507,13 +507,24 @@ linters-settings:
disable-all: false

depguard:
list-type: blacklist
list-type: denylist
include-go-root: false
packages:
- github.com/sirupsen/logrus
packages-with-error-message:
# specify an error message to output when a blacklisted package is used
# specify an error message to output when a denied package is used
- github.com/sirupsen/logrus: "logging is allowed only by logutils.Log"
# create additional guards that follow the same configuration pattern
# results from all guards are aggregated together
additional-guards:
- list-type: denylist
include-go-root: false
packages:
- github.com/stretchr/testify
# specify rules by which the linter ignores certain files for consideration
ignore-file-rules:
- "**/*_test.go"
- "**/mock/**/*.go"

ifshort:
# Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax.
Expand Down
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
linters-settings:
depguard:
list-type: blacklist
list-type: denylist
timkral marked this conversation as resolved.
Show resolved Hide resolved
packages:
# logging is allowed only by logutils.Log, logrus
# is allowed to use only in logutils package
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/Antonboom/nilnil v0.1.0
github.com/BurntSushi/toml v0.4.1
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
github.com/OpenPeeDeeP/depguard v1.0.1
github.com/OpenPeeDeeP/depguard v1.1.0
github.com/alexkohler/prealloc v1.0.0
github.com/ashanbrown/forbidigo v1.2.0
github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde
Expand Down
6 changes: 4 additions & 2 deletions go.sum

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

4 changes: 4 additions & 0 deletions pkg/commands/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ func initFlagSet(fs *pflag.FlagSet, cfg *config.Config, m *lintersdb.Manager, is
"Depguard: check list against standard lib")
hideFlag("depguard.include-go-root")

fs.StringSliceVar(&lsc.Depguard.IgnoreFileRules, "depguard.ignore-file-rules", nil,
"Depguard: rules to ignore certain files for consideration")
hideFlag("depguard.ignore-file-rules")

ldez marked this conversation as resolved.
Show resolved Hide resolved
fs.IntVar(&lsc.Lll.TabWidth, "lll.tab-width", 1,
"Lll: tab width in spaces")
hideFlag("lll.tab-width")
Expand Down
8 changes: 8 additions & 0 deletions pkg/config/linters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ type DepGuardSettings struct {
Packages []string
IncludeGoRoot bool `mapstructure:"include-go-root"`
PackagesWithErrorMessage map[string]string `mapstructure:"packages-with-error-message"`
IgnoreFileRules []string `mapstructure:"ignore-file-rules"`
AdditionalGuards []struct {
ldez marked this conversation as resolved.
Show resolved Hide resolved
ListType string `mapstructure:"list-type"`
Packages []string
IncludeGoRoot bool `mapstructure:"include-go-root"`
PackagesWithErrorMessage map[string]string `mapstructure:"packages-with-error-message"`
IgnoreFileRules []string `mapstructure:"ignore-file-rules"`
} `mapstructure:"additional-guards"`
}

type DecorderSettings struct {
Expand Down
127 changes: 90 additions & 37 deletions pkg/golinters/depguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,75 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/loader" //nolint:staticcheck // require changes in github.com/OpenPeeDeeP/depguard

"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"
)

func setDepguardListType(dg *depguard.Depguard, lintCtx *linter.Context) error {
listType := lintCtx.Settings().Depguard.ListType
func parseDepguardSettings(dgSettings *config.DepGuardSettings) (map[*depguard.Depguard]map[string]string, error) {
parsedDgSettings := make(map[*depguard.Depguard]map[string]string)
dg := &depguard.Depguard{
Packages: dgSettings.Packages,
IncludeGoRoot: dgSettings.IncludeGoRoot,
IgnoreFileRules: dgSettings.IgnoreFileRules,
}

if err := setDepguardListType(dg, dgSettings.ListType); err != nil {
return nil, err
}
setupDepguardPackages(dg, dgSettings.PackagesWithErrorMessage)
if dgSettings.PackagesWithErrorMessage != nil {
parsedDgSettings[dg] = dgSettings.PackagesWithErrorMessage
} else {
parsedDgSettings[dg] = make(map[string]string)
}

for _, additionalGuard := range dgSettings.AdditionalGuards {
additionalDg := &depguard.Depguard{
Packages: additionalGuard.Packages,
IncludeGoRoot: additionalGuard.IncludeGoRoot,
IgnoreFileRules: additionalGuard.IgnoreFileRules,
}

if err := setDepguardListType(additionalDg, additionalGuard.ListType); err != nil {
return nil, err
}
setupDepguardPackages(additionalDg, additionalGuard.PackagesWithErrorMessage)
if additionalGuard.PackagesWithErrorMessage != nil {
parsedDgSettings[additionalDg] = additionalGuard.PackagesWithErrorMessage
} else {
parsedDgSettings[additionalDg] = make(map[string]string)
}
}

return parsedDgSettings, nil
}

func postProcessIssue(
issue *depguard.Issue,
dg *depguard.Depguard,
packagesWithErrorMessage map[string]string,
lintCtx *linter.Context,
) *result.Issue {
msgSuffix := "is in the blacklist"
if dg.ListType == depguard.LTWhitelist {
msgSuffix = "is not in the whitelist"
}

userSuppliedMsgSuffix := packagesWithErrorMessage[issue.PackageName]
if userSuppliedMsgSuffix != "" {
userSuppliedMsgSuffix = ": " + userSuppliedMsgSuffix
}

return &result.Issue{
Pos: issue.Position,
Text: fmt.Sprintf("%s %s%s", formatCode(issue.PackageName, lintCtx.Cfg), msgSuffix, userSuppliedMsgSuffix),
FromLinter: linterName,
}
}

func setDepguardListType(dg *depguard.Depguard, listType string) error {
var found bool
dg.ListType, found = depguard.StringToListType[strings.ToLower(listType)]
if !found {
Expand All @@ -28,7 +90,10 @@ func setDepguardListType(dg *depguard.Depguard, lintCtx *linter.Context) error {
return nil
}

func setupDepguardPackages(dg *depguard.Depguard, lintCtx *linter.Context) {
func setupDepguardPackages(
dg *depguard.Depguard,
packagesWithErrorMessage map[string]string,
) {
ldez marked this conversation as resolved.
Show resolved Hide resolved
if dg.ListType == depguard.LTBlacklist {
// if the list type was a blacklist the packages with error messages should
// be included in the blacklist package list
Expand All @@ -38,16 +103,17 @@ func setupDepguardPackages(dg *depguard.Depguard, lintCtx *linter.Context) {
noMessagePackages[pkg] = true
}

for pkg := range lintCtx.Settings().Depguard.PackagesWithErrorMessage {
for pkg := range packagesWithErrorMessage {
if _, ok := noMessagePackages[pkg]; !ok {
dg.Packages = append(dg.Packages, pkg)
}
}
}
}

const linterName = "depguard"

func NewDepguard() *goanalysis.Linter {
const linterName = "depguard"
var mu sync.Mutex
var resIssues []goanalysis.Issue

Expand All @@ -63,47 +129,34 @@ func NewDepguard() *goanalysis.Linter {
).WithContextSetter(func(lintCtx *linter.Context) {
dgSettings := &lintCtx.Settings().Depguard
analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
prog := goanalysis.MakeFakeLoaderProgram(pass)
dg := &depguard.Depguard{
Packages: dgSettings.Packages,
IncludeGoRoot: dgSettings.IncludeGoRoot,
}
if err := setDepguardListType(dg, lintCtx); err != nil {
parsedDgSettings, err := parseDepguardSettings(dgSettings)
if err != nil {
return nil, err
}
setupDepguardPackages(dg, lintCtx)

loadConfig := &loader.Config{
Cwd: "", // fallbacked to os.Getcwd
Build: nil, // fallbacked to build.Default
}
issues, err := dg.Run(loadConfig, prog)
if err != nil {
return nil, err
}
if len(issues) == 0 {
return nil, nil
}
ldez marked this conversation as resolved.
Show resolved Hide resolved
msgSuffix := "is in the blacklist"
if dg.ListType == depguard.LTWhitelist {
msgSuffix = "is not in the whitelist"
}
res := make([]goanalysis.Issue, 0, len(issues))
for _, i := range issues {
userSuppliedMsgSuffix := dgSettings.PackagesWithErrorMessage[i.PackageName]
if userSuppliedMsgSuffix != "" {
userSuppliedMsgSuffix = ": " + userSuppliedMsgSuffix
prog := goanalysis.MakeFakeLoaderProgram(pass)

for dg, packagesWithErrorMessage := range parsedDgSettings {
issues, err := dg.Run(loadConfig, prog)
if err != nil {
return nil, err
}
if len(issues) == 0 {
return nil, nil
}
res = append(res, goanalysis.NewIssue(&result.Issue{
Pos: i.Position,
Text: fmt.Sprintf("%s %s%s", formatCode(i.PackageName, lintCtx.Cfg), msgSuffix, userSuppliedMsgSuffix),
FromLinter: linterName,
}, pass))
res := make([]goanalysis.Issue, 0, len(issues))
for _, i := range issues {
lintIssue := postProcessIssue(i, dg, packagesWithErrorMessage, lintCtx)
res = append(res, goanalysis.NewIssue(lintIssue, pass))
}
mu.Lock()
resIssues = append(resIssues, res...)
mu.Unlock()
}
mu.Lock()
resIssues = append(resIssues, res...)
mu.Unlock()

return nil, nil
}
}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
Expand Down
16 changes: 16 additions & 0 deletions test/testdata/configs/depguard_additional_guards.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
linters-settings:
depguard:
list-type: denylist
include-go-root: true
packages:
- compress/*
packages-with-error-message:
log: "don't use log"
additional-guards:
- list-type: denylist
include-go-root: true
packages:
- fmt
packages-with-error-message:
strings: "disallowed in additional guard"

10 changes: 10 additions & 0 deletions test/testdata/configs/depguard_ignore_file_rules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
linters-settings:
depguard:
list-type: denylist
include-go-root: true
packages:
- compress/*
packages-with-error-message:
log: "don't use log"
ignore-file-rules:
- "**/*_ignore_file_rules.go"
16 changes: 16 additions & 0 deletions test/testdata/depguard_additional_guards.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//args: -Edepguard
//config_path: testdata/configs/depguard_additional_guards.yml
package testdata

import (
"compress/gzip" // ERROR "`compress/gzip` is in the blacklist"
"fmt" // ERROR "`fmt` is in the blacklist"
"log" // ERROR "`log` is in the blacklist: don't use log"
"strings" // ERROR "`strings` is in the blacklist: disallowed in additional guard"
)

func SpewDebugInfo() {
log.Println(gzip.BestCompression)
log.Println(fmt.Sprintf("SpewDebugInfo"))
log.Println(strings.ToLower("SpewDebugInfo"))
}
13 changes: 13 additions & 0 deletions test/testdata/depguard_ignore_file_rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//args: -Edepguard
//config_path: testdata/configs/depguard_ignore_file_rules.yml
package testdata

// NOTE - No lint errors becuase this file is ignored
import (
"compress/gzip"
"log"
)

func SpewDebugInfo() {
log.Println(gzip.BestCompression)
}