Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

It consists of several analyzers:
1. `unused`: Detects interfaces which are not used anywhere in the same package where they are defined.
2. `identical`: Detects interfaces within the same package that have identical methods or type constraints.
3. `opaque`: Detects functions that return an interface type, but only ever return a single concrete implementation.
4. `unexported`: Detects interfaces which are not exported but are used as parameters or return values in exported functions or methods.
2. `unusedmethod`: Detects interface methods that are never used anywhere in the same package where they are defined.
3. `identical`: Detects interfaces within the same package that have identical methods or type constraints.
4. `opaque`: Detects functions that return an interface type, but only ever return a single concrete implementation.
5. `unexported`: Detects interfaces which are not exported but are used as parameters or return values in exported functions or methods.

## Usage

Expand All @@ -20,6 +21,7 @@ go install github.com/uudashr/iface/cmd/ifacecheck@latest
To install individual linter, use the following command:
```sh
go install github.com/uudashr/iface/unused/cmd/unusediface@latest
go install github.com/uudashr/iface/unusedmethod/cmd/unusedmethodiface@latest
go install github.com/uudashr/iface/identical/cmd/identicaliface@latest
go install github.com/uudashr/iface/opaque/cmd/opaqueiface@latest
go install github.com/uudashr/iface/unexported/cmd/unexportediface@latest
Expand Down Expand Up @@ -49,11 +51,12 @@ By default it only enables the `identical` analyzer, you need to enable them all

### Package exclusion

We encourage using the default behavior and making an effort to follow the rules. However, in some cases the rules may not apply. Due to this we can exclude specific package to be scanned by the analyzers. Use `-unused.exclude` flag and currently only `unused` has this feature. See help for more information:
We encourage using the default behavior and making an effort to follow the rules. However, in some cases the rules may not apply. Due to this we can exclude specific package to be scanned by the analyzers. Use `-unused.exclude` or `-unusedmethod.exclude` flag. See help for more information:

Example usage:
```sh
ifacecheck -unused.exclude=github.com/example/log ./...
ifacecheck -unusedmethod.exclude=github.com/example/log ./...
```

### Ignore Directive
Expand Down
2 changes: 2 additions & 0 deletions cmd/ifacecheck/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import (
"github.com/uudashr/iface/opaque"
"github.com/uudashr/iface/unexported"
"github.com/uudashr/iface/unused"
"github.com/uudashr/iface/unusedmethod"
"golang.org/x/tools/go/analysis/multichecker"
)

func main() {
multichecker.Main(
unused.Analyzer,
unusedmethod.Analyzer,
identical.Analyzer,
opaque.Analyzer,
unexported.Analyzer,
Expand Down
10 changes: 10 additions & 0 deletions unusedmethod/cmd/unusedmethodiface/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

import (
"github.com/uudashr/iface/unusedmethod"
"golang.org/x/tools/go/analysis/singlechecker"
)

func main() {
singlechecker.Main(unusedmethod.Analyzer)
}
3 changes: 3 additions & 0 deletions unusedmethod/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package unusedmethod defines an Analyzer that detects interface methods which
// are never used anywhere in the same package where they are defined.
package unusedmethod
23 changes: 23 additions & 0 deletions unusedmethod/testdata/src/a/a.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package comm

type MessageSender interface {
SendMessage(username, msg string) error
MustSendMessage(username, msg string) // want "method 'MustSendMessage\\(\\)' is declared on interface 'MessageSender' but not used within the package"

// Close the resource.
Close() error // want "method 'Close\\(\\)' is declared on interface 'MessageSender' but not used within the package"
}

type Service struct {
sender MessageSender
}

func NewService(sender MessageSender) *Service {
return &Service{
sender: sender,
}
}

func (s *Service) GreetMorning(username string) error {
return s.sender.SendMessage(username, "Good morning")
}
19 changes: 19 additions & 0 deletions unusedmethod/testdata/src/a/a.go.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package comm

type MessageSender interface {
SendMessage(username, msg string) error
}

type Service struct {
sender MessageSender
}

func NewService(sender MessageSender) *Service {
return &Service{
sender: sender,
}
}

func (s *Service) GreetMorning(username string) error {
return s.sender.SendMessage(username, "Good morning")
}
24 changes: 24 additions & 0 deletions unusedmethod/testdata/src/b/b.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package comm

//iface:ignore=unusedmethod
type MessageSender interface {
SendMessage(username, msg string) error
MustSendMessage(username, msg string)

// Close the resource.
Close() error
}

type Service struct {
sender MessageSender
}

func NewService(sender MessageSender) *Service {
return &Service{
sender: sender,
}
}

func (s *Service) GreetMorning(username string) error {
return s.sender.SendMessage(username, "Good morning")
}
25 changes: 25 additions & 0 deletions unusedmethod/testdata/src/c/c.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package comm

type MessageSender interface {
SendMessage(username, msg string) error

//iface:ignore=unusedmethod
MustSendMessage(username, msg string)

// Close the resource.
Close() error // want "method 'Close\\(\\)' is declared on interface 'MessageSender' but not used within the package"
}

type Service struct {
sender MessageSender
}

func NewService(sender MessageSender) *Service {
return &Service{
sender: sender,
}
}

func (s *Service) GreetMorning(username string) error {
return s.sender.SendMessage(username, "Good morning")
}
23 changes: 23 additions & 0 deletions unusedmethod/testdata/src/d/d.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package comm

type MessageSender interface {
SendMessage(username, msg string) error
MustSendMessage(username, msg string) //iface:ignore=unusedmethod

// Close the resource.
Close() error // want "method 'Close\\(\\)' is declared on interface 'MessageSender' but not used within the package"
}

type Service struct {
sender MessageSender
}

func NewService(sender MessageSender) *Service {
return &Service{
sender: sender,
}
}

func (s *Service) GreetMorning(username string) error {
return s.sender.SendMessage(username, "Good morning")
}
13 changes: 13 additions & 0 deletions unusedmethod/testdata/src/e/e.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package comm

type Callback interface {
Call(msg string)
}

type Service struct {
callbacks []func(msg string)
}

func (s *Service) RegisterCallaback(cb Callback) {
s.callbacks = append(s.callbacks, cb.Call)
}
20 changes: 20 additions & 0 deletions unusedmethod/testdata/src/f/f.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package comm

type Callback interface {
Call(msg string)
}

type entry struct {
cb Callback
call func(cb Callback, msg string)
}
type Service struct {
callbacks []entry
}

func (s *Service) RegisterCallaback(cb Callback) {
s.callbacks = append(s.callbacks, entry{
cb: cb,
call: Callback.Call,
})
}
23 changes: 23 additions & 0 deletions unusedmethod/testdata/src/g/a.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package comm

type MessageSender interface {
SendMessage(username, msg string) error
MustSendMessage(username, msg string)

// Close the resource.
Close() error
}

type Service struct {
sender MessageSender
}

func NewService(sender MessageSender) *Service {
return &Service{
sender: sender,
}
}

func (s *Service) GreetMorning(username string) error {
return s.sender.SendMessage(username, "Good morning")
}
19 changes: 19 additions & 0 deletions unusedmethod/testdata/src/g/a.go.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package comm

type MessageSender interface {
SendMessage(username, msg string) error
}

type Service struct {
sender MessageSender
}

func NewService(sender MessageSender) *Service {
return &Service{
sender: sender,
}
}

func (s *Service) GreetMorning(username string) error {
return s.sender.SendMessage(username, "Good morning")
}
Loading
Loading