Interfacer - A linter that suggests interface types

Overview

interfacer

GoDoc Build Status

Deprecated: A tool that suggests interfaces is prone to bad suggestions, so its usefulness in real code is limited. This tool will remain available as a proof of concept, and for others to examine and learn from.

A linter that suggests interface types. In other words, it warns about the usage of types that are more specific than necessary.

go get -u mvdan.cc/interfacer

Note that this linter's suggestions tend to be subjective, as interfaces are not always the better option. You should select the proposed changes that make sense in your codebase, instead of following all of them blindly.

Usage

func ProcessInput(f *os.File) error {
        b, err := ioutil.ReadAll(f)
        if err != nil {
                return err
        }
        return processBytes(b)
}
$ interfacer ./...
foo.go:10:19: f can be io.Reader

Basic idea

This tool inspects the parameters of your functions to see if they fit an interface type that is less specific than the current type.

The example above illustrates this point. Overly specific interfaces also trigger a warning - if f were an io.ReadCloser, the same message would appear.

It suggests interface types defined both in the func's package and the package's imports (two levels; direct imports and their direct imports).

False positives

To avoid false positives, it never does any suggestions on functions that may be implementing an interface method or a named function type.

It also skips parameters passed by value (excluding pointers and interfaces) on unexported functions, since that would introduce extra allocations where they are usually not worth the tradeoff.

Suppressing warnings

If a suggestion is technically correct but doesn't make sense, you can still suppress the warning by mentioning the type in the function name:

func ProcessInputFile(f *os.File) error {
	// use as an io.Reader
}
Comments
  • Recognize embeded interfaces

    Recognize embeded interfaces

    I have interface:

    type IBusinessRuleContext interface {
        IRWLocker
        Value(interface{}) interface{}
    }
    type IRWLocker interface {
        sync.Locker
        RLock()
        RUnlock()
    }
    

    And when i create some object with type IBusinessRuleContext interfacer suggests: {MyType} can be sync.Locker

    But sync.Locker is embedded to IRWLocker and it embedded to biggest interface IBusinessRuleContext.

    opened by nizsheanez 9
  • Poorly behaved on *_test files

    Poorly behaved on *_test files

    I have been running interfacer with neomake whenever I save a golang file. This has been working fine, until I attempted to edit a _test.go file, where I recieved the following error:

    $ interfacer smlr/http_test.go 
    smlr/http_test.go:22:12: undeclared name: HTTPWaiter
    

    (where HTTPWaiter is declared in `smlr/http.go). Many other tools handle this discrepancy well, I wonder if interfacer could.

    Unfortunately, I can't tell you what version of interfacer this is:

    $ interfacer --version
    flag provided but not defined: -version
    Usage of interfacer:
      -v    print the names of packages as they are checked
    

    Here is my neomake configuration, if that helps:

    let g:neomake_go_interfacer_maker = {
        \ 'errorformat': '%f:%l:%c: %m'
        \ }
    let g:neomake_go_enabled_makers = ['go', 'golint', 'govet', 'interfacer']
    
    bug 
    opened by langston-barrett 8
  • Not getting output for your `readme.md`s example

    Not getting output for your `readme.md`s example

    Copied the example in readme.md nearly verbatim into here (senseless code but just attempting to evade any potential compiler-side code removal..) but interfacer github.com/metaleap/go-devgo works for some 1-3 secs but prints nothing, same with interfacer -v github.com/metaleap/go-devgo --- what am I missing?

    bug 
    opened by metaleap 7
  • Provide --version flag

    Provide --version flag

    It's good for debugging/reporting errors!

    $ interfacer --version
    flag provided but not defined: -version
    Usage of interfacer:
      -v    print the names of packages as they are checked
    
    opened by langston-barrett 7
  • Check nil pointer

    Check nil pointer

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal 0xc0000005 code=0x0 addr=0x0 pc=0x47db18]
    
    goroutine 1 [running]:
    github.com/mvdan/interfacer.orderedPkgs(0xc0820075c0, 0x0, 0x0, 0x0, 0x0, 0x0)
            c:/dev/godev/src/github.com/mvdan/interfacer/check.go:105 +0x328
    github.com/mvdan/interfacer.CheckArgs(0xc0820046f0, 0x1, 0x1, 0xaa46f0, 0xc082022010, 0x404400, 0x0, 0x0)
            c:/dev/godev/src/github.com/mvdan/interfacer/check.go:123 +0x1c8
    main.main()
            c:/dev/godev/src/github.com/mvdan/interfacer/cmd/interfacer/main.go:20 +0xab
    
    opened by mattn 7
  • Could we ignore the vendor folder?

    Could we ignore the vendor folder?

    I noticed that the vendor folder is included in the results from interfacer. The vendor folder is a little beyond my control and I don't think that interfacer should check the vendor folder.

    For example, one of my projects vendors github.com/stretchr/testify and I see this error from interfacer:

    interfacer ./...
    vendor/github.com/stretchr/testify/mock/mock.go:276:36: t can be assert.TestingT
    
    opened by dmowcomber 5
  • Fails on unknown field

    Fails on unknown field

    Running the tool on the follow code fails with the error:

    $ interfacer ./...
    p/a/t/h/main.go:185:3: unknown field Pdeathsig in struct literal
    
    cmd := exec.Command("foo")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Pdeathsig: syscall.SIGTERM,
    }
    
    opened by djui 5
  • [readme.md] so, what exactly is `go/loader`?

    [readme.md] so, what exactly is `go/loader`?

    In the repo readme:

    This package relies on go/types for the heavy lifting: name resolution, constant folding and type inference. It also uses go/loader to resolve the packages specified by import paths.

    I'd be curious to use the latter in other code, but I don't find any actual go/loader imports in your .go sources here and no mention of loader at https://golang.org/pkg/go/ either --- what is it?

    opened by metaleap 3
  • README: Skip /vendor/ folders in usage example.

    README: Skip /vendor/ folders in usage example.

    This is a better default usage example. Most people want to run the tool on code they control, not vendored code that cannot be modified.

    Updates #27. Fixes #29.

    opened by dmitshur 3
  • It is better for interfacer not to analyze vendor folder

    It is better for interfacer not to analyze vendor folder

    interfacer is a good tool for gophers. I have tried it and got many help. I have a small issue that is currently the interfacer tries to analyze the vendor folder in the golang repo. In my opinion, It is better for interfacer not to analyze vendor folder.

    $interfacer ./...
    /Users/tony/Test/GoToolsProjects/src/app-weixin/vendor/github.com/astaxie/beego/session/couchbase/sess_couchbase.go:40:12: could not import github.com/couchbase/go-couchbase (cannot find package "github.com/couchbase/go-couchbase" in any of:
    	/Users/tony/Test/GoToolsProjects/src/app-weixin/vendor/github.com/couchbase/go-couchbase (vendor tree)
    	/Users/tony/.bin/go17/src/github.com/couchbase/go-couchbase (from $GOROOT)
    	/Users/tony/Test/GoToolsProjects/src/github.com/couchbase/go-couchbase (from $GOPATH))
    
    opened by bigwhite 3
  • inconsistent definition for type ssa.NamedConst during import

    inconsistent definition for type ssa.NamedConst during import

    When I run : go get -u github.com/mvdan/interfacer/cmd/interfacer I get:

    ../../mvdan/interfacer/check.go:19: inconsistent definition for type ssa.NamedConst during import struct { ssa.object *types.Const; Value *ssa.Const; ssa.pkg *ssa.Package } (in "golang.org/x/tools/go/ssa") struct { ssa.object *types.Const; Value *ssa.Const; ssa.pos token.Pos; ssa.pkg *ssa.Package } (in "github.com/mvdan/lint")

    ../../mvdan/interfacer/check.go:19: method redeclared: ssa.Program.CreateTestMainPackage method(*ssa.Program) func(*ssa.Package) *ssa.Package method(*ssa.Program) func(...*ssa.Package) *ssa.Package

    opened by wgliang 2
Owner
Daniel Martí
I work on stuff in Go.
Daniel Martí
[mirror] This is a linter for Go source code.

Golint is a linter for Go source code. Installation Golint requires a supported release of Go. go get -u golang.org/x/lint/golint To find out where g

Go 4k Dec 23, 2022
Staticcheck - The advanced Go linter

The advanced Go linter Staticcheck is a state of the art linter for the Go programming language. Using static analysis, it finds bugs and performance

Dominik Honnef 5.1k Jan 1, 2023
A Go linter to check that errors from external packages are wrapped

Wrapcheck A simple Go linter to check that errors from external packages are wrapped during return to help identify the error source during debugging.

Tom Arrell 204 Dec 27, 2022
A linter that handles struct tags.

Tagliatelle A linter that handles struct tags. Supported string casing: camel pascal kebab snake goCamel Respects Go's common initialisms (e.g. HttpRe

Ludovic Fernandez 20 Dec 15, 2022
a simple golang SSA viewer tool use for code analysis or make a linter

ssaviewer A simple golang SSA viewer tool use for code analysis or make a linter ssa.html generate code modify from src/cmd/compile/internal/ssa/html.

null 7 May 17, 2022
The Golang linter that checks that there is no simultaneous return of `nil` error and an invalid value.

nilnil Checks that there is no simultaneous return of nil error and an invalid value. Installation & usage $ go install github.com/Antonboom/[email protected]

Anton Telyshev 13 Dec 14, 2022
Go linter which checks for dangerous unicode character sequences

bidichk - checks for dangerous unicode character sequences bidichk finds dangerous unicode character sequences in Go source files. Considered dangerou

Lucas Bremgartner 27 Oct 5, 2022
Linter for PostgreSQL

Использование Проверить миграции: oh-my-pg-linter check ./migrations/*.sql Добавить директории с дополнительными проверками (переопределение - кто пос

Denis Kayumov 0 Nov 25, 2021
containedctx detects is a linter that detects struct contained context.Context field

containedctx containedctx detects is a linter that detects struct contained context.Context field Instruction go install github.com/sivchari/contained

sivchari 12 Oct 22, 2022
World's spookiest linter

nosleep The world's spookiest linter nosleep is a golang-ci compatible linter which checks for and fails if it detects usages of time.Sleep. Why did y

Elliot Williams 1 Oct 15, 2022
Go linter to analyze expression groups: require 'import' declaration groups

grouper — a Go linter to analyze expression groups Installation

null 0 Jun 19, 2022
funcresult — a Go linter to analyze function result parameters

Go linter to analyze function result parameters: require named / unnamed function result parameters

null 0 Jan 27, 2022
nostdglobals is a simple Go linter that checks for usages of global variables defined in the go standard library

nostdglobals is a simple Go linter that checks for usages of global variables defined in the go standard library

Nassos Kat 1 Feb 17, 2022
Goalinter-v1: Goa framework (version1) linter

goavl: Goa framework (ver1) linter goavlは、goa version1(フォーク版)のlinterです。開発目的は、goa

CHIKAMATSU Naohiro 1 Jul 28, 2022
Linter for Go's fmt.Errorf message

wrapmsg wrapmsg is Go code linter. this enforces fmt.Errorf's message when you wrap error. Example // OK ???? if err := pkg.Cause(); err != nil { re

Shinnosuke Sawada 12 Dec 27, 2022
misspelled word linter for Go comments, string literals and embedded files

gospel The gospel program lints Go source files for misspellings in comments, strings and embedded files. It uses hunspell to identify misspellings an

Dan Kortschak 30 Aug 6, 2022
dont-interface calculates how many interface{} are declared or used in your project?

dont-interface calculates how many interface{} are declared or used in your project?

Ray Eldath 17 Jun 9, 2022
Type check the empty interface{}

Static type checker for interface{} with a type list This is an experiment. This is a tool that performs a static type check on values of type interfa

Sina Siadat 15 Sep 13, 2021
Plugs module to see different types of plug types needed in different countries, and a comparison tool between two countries plug socket types.

plugs Importing the module: go get github.com/matthewboyd/plugs "github.com/matthewboyd/plugs" How to use the module: There are two functions wi

Matthew Boyd 2 Dec 28, 2021
Small gh extension that suggests issues to work on in a given GitHub repository

gh contribute being a gh extension for finding issues to help with in a GitHub repository. This extension suggests an issue in a given repository to w

Nate Smith 25 Dec 24, 2022