Skip to content

Commit

Permalink
review
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez committed Sep 18, 2024
1 parent 76a37b6 commit 9cc3432
Show file tree
Hide file tree
Showing 17 changed files with 338 additions and 140 deletions.
5 changes: 3 additions & 2 deletions .golangci.next.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1223,15 +1223,16 @@ linters-settings:
var-require-grouping: true

iface:
# By default set to empty. Leave it empty means all analyzers are enabled.
# By default, set to empty.
# Empty means that all analyzers are enabled.
# Default: []
enable:
- unused
- identical
- opaque
settings:
unused:
# Comma-separated list of packages to exclude from the check.
# List of packages path to exclude from the check.
# Default: []
exclude:
- github.com/example/log
Expand Down
11 changes: 11 additions & 0 deletions jsonschema/golangci.next.jsonschema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,17 @@
"items": {
"$ref": "#/definitions/iface-analyzers"
}
},
"settings": {
"type": "object",
"propertyNames": {
"$ref": "#/definitions/iface-analyzers"
},
"patternProperties": {
"^.*$": {
"type": "object"
}
}
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion pkg/config/linters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,8 @@ type GrouperSettings struct {
}

type IfaceSettings struct {
Enable []string `mapstructure:"enable"`
Enable []string `mapstructure:"enable"`
Settings map[string]map[string]any `mapstructure:"settings"`
}

type ImportAsSettings struct {
Expand Down
54 changes: 16 additions & 38 deletions pkg/golinters/iface/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,69 +6,47 @@ import (
"github.com/uudashr/iface/identical"
"github.com/uudashr/iface/opaque"
"github.com/uudashr/iface/unused"
"golang.org/x/exp/maps"
"golang.org/x/tools/go/analysis"

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

var allAnalyzers = []*analysis.Analyzer{
unused.Analyzer,
identical.Analyzer,
opaque.Analyzer,
}

func New(settings *config.IfaceSettings) *goanalysis.Linter {
var conf map[string]map[string]any

analyzers := analyzersFromSettings(settings)
if settings != nil {
conf = settings.Settings
}

return goanalysis.NewLinter(
"iface",
"Detect the incorrect use of interfaces, helping developers avoid interface pollution.",
analyzers,
analyzersFromSettings(settings),
conf,
).WithLoadMode(goanalysis.LoadModeTypesInfo)
}

func analyzersFromSettings(settings *config.IfaceSettings) []*analysis.Analyzer {
if settings == nil || len(settings.Enable) == 0 {
return allAnalyzers
allAnalyzers := map[string]*analysis.Analyzer{
"unused": unused.Analyzer,
"identical": identical.Analyzer,
"opaque": opaque.Analyzer,
}

enabledNames := uniqueNames(settings.Enable)
if settings == nil || len(settings.Enable) == 0 {
return maps.Values(allAnalyzers)
}

var analyzers []*analysis.Analyzer

for _, a := range allAnalyzers {
found := slices.ContainsFunc(enabledNames, func(name string) bool {
return name == a.Name
})

if !found {
continue
}

analyzers = append(analyzers, a)
for _, name := range uniqueNames(settings.Enable) {
analyzers = append(analyzers, allAnalyzers[name])
}

return analyzers
}

func uniqueNames(names []string) []string {
if len(names) == 0 {
return nil
}

namesMap := map[string]struct{}{}
for _, name := range names {
namesMap[name] = struct{}{}
}

uniqueNames := make([]string, 0, len(namesMap))

for name := range namesMap {
uniqueNames = append(uniqueNames, name)
}
return uniqueNames
slices.Sort(names)
return slices.Compact(names)
}
61 changes: 0 additions & 61 deletions pkg/golinters/iface/iface_test.go

This file was deleted.

11 changes: 0 additions & 11 deletions pkg/golinters/iface/testdata/identical.go

This file was deleted.

64 changes: 64 additions & 0 deletions pkg/golinters/iface/testdata/iface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//golangcitest:args -Eiface
package testdata

// identical

type Pinger interface { // want "unused: interface Pinger is declared but not used within the package"
Ping() error
}

type Healthcheck interface { // want "unused: interface Healthcheck is declared but not used within the package"
Ping() error
}

// opaque

type Server interface {
Serve() error
}

type server struct {
addr string
}

func (s server) Serve() error {
return nil
}

func NewServer(addr string) Server { // want "opaque: NewServer function return Server interface at the 1st result, abstract a single concrete implementation of \\*server"
return &server{addr: addr}
}

// unused

type User struct {
ID string
Name string
}

type UserRepository interface { // want "unused: interface UserRepository is declared but not used within the package"
UserOf(id string) (*User, error)
}

type UserRepositorySQL struct {
}

func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}

type Granter interface {
Grant(permission string) error
}

func AllowAll(g Granter) error {
return g.Grant("all")
}

type Allower interface {
Allow(permission string) error
}

func Allow(x interface{}) {
_ = x.(Allower)
}
65 changes: 65 additions & 0 deletions pkg/golinters/iface/testdata/iface_identical.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//golangcitest:args -Eiface
//golangcitest:config_path testdata/iface_identical.yml
package testdata

// identical

type Pinger interface { // want "identical: interface Pinger contains identical methods or type constraints from another interface, causing redundancy"
Ping() error
}

type Healthcheck interface { // want "identical: interface Healthcheck contains identical methods or type constraints from another interface, causing redundancy"
Ping() error
}

// opaque

type Server interface {
Serve() error
}

type server struct {
addr string
}

func (s server) Serve() error {
return nil
}

func NewServer(addr string) Server {
return &server{addr: addr}
}

// unused

type User struct {
ID string
Name string
}

type UserRepository interface {
UserOf(id string) (*User, error)
}

type UserRepositorySQL struct {
}

func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
return nil, nil
}

type Granter interface {
Grant(permission string) error
}

func AllowAll(g Granter) error {
return g.Grant("all")
}

type Allower interface {
Allow(permission string) error
}

func Allow(x interface{}) {
_ = x.(Allower)
}
File renamed without changes.
Loading

0 comments on commit 9cc3432

Please sign in to comment.