Skip to content

Commit

Permalink
Merge remote-tracking branch 'base/master' into feature/update-v1.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
rjacobs31 committed Apr 29, 2024
2 parents 8e7847f + b65821b commit ad712ca
Show file tree
Hide file tree
Showing 18 changed files with 284 additions and 234 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/errcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: errcheck

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
strategy:
matrix:
go: ["1.18.x", "1.19.x", "1.20.x", "1.21.x", "1.22.x"]
name: go ${{ matrix.go }}
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
- name: Build
run: go build -v ./...
- name: Test
run: go test -v ./...
30 changes: 0 additions & 30 deletions .github/workflows/go.yml

This file was deleted.

16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# errcheck

errcheck is a program for checking for unchecked errors in go programs.
errcheck is a program for checking for unchecked errors in Go code.

![Go](https://github.com/getkalido/errcheck/workflows/Go/badge.svg)

Expand All @@ -26,7 +26,7 @@ The Author is, of course, entitled to his opinion. But those who disagree with h

go install github.com/getkalido/errcheck@latest

errcheck requires Go 1.14 or newer and depends on the package go/packages from the golang.org/x/tools repository.
errcheck requires Go 1.18 or newer.

## Use

Expand All @@ -38,7 +38,7 @@ To check all packages beneath the current directory:

errcheck ./...

Or check all packages in your $GOPATH and $GOROOT:
Or check all packages in your `$GOPATH` and `$GOROOT`:

errcheck all

Expand All @@ -54,13 +54,17 @@ takes no arguments.
The `-blank` flag enables checking for assignments of errors to the
blank identifier. It takes no arguments.

The `-abspath` flag prints the absolute paths to files with unchecked errors.

The `-mod` flag sets the module download mode to use: `readonly` or `vendor`.

### go/analysis

The package provides `Analyzer` instance that can be used with
[go/analysis](https://pkg.go.dev/golang.org/x/tools/go/analysis) API.

Currently supported flags are `blank`, `assert`, `exclude`, and `excludeonly`.
Just as the API itself, the analyzer is exprimental and may change in the
Just as the API itself, the analyzer is experimental and may change in the
future.

## Excluding functions
Expand All @@ -78,9 +82,9 @@ the the function call is excluded only if the type of the first argument is `TYP

An example of an exclude file is:

io/ioutil.ReadFile
io.Copy(*bytes.Buffer)
io.Copy(os.Stdout)
os.ReadFile

// Sometimes we don't care if a HTTP request fails.
(*net/http.Client).Do
Expand Down Expand Up @@ -138,6 +142,8 @@ specified for it. To disable this, specify a regex that matches nothing:
The `-ignoretests` flag disables checking of `_test.go` files. It takes
no arguments.

The `-ignoregenerated` flag disables checking of generated source code. It takes no arguments.

## Exit Codes

errcheck returns 1 if any problems were found in the checked files.
Expand Down
7 changes: 3 additions & 4 deletions errcheck/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package errcheck
import (
"fmt"
"go/ast"
"go/token"
"reflect"
"regexp"

Expand Down Expand Up @@ -32,7 +31,6 @@ func init() {
}

func runAnalyzer(pass *analysis.Pass) (interface{}, error) {

exclude := map[string]bool{}
if !argExcludeOnly {
for _, name := range DefaultExcludedSymbols {
Expand Down Expand Up @@ -66,8 +64,9 @@ func runAnalyzer(pass *analysis.Pass) (interface{}, error) {

for _, err := range v.errors {
pass.Report(analysis.Diagnostic{
Pos: token.Pos(int(f.Pos()) + err.Pos.Offset),
Message: "unchecked error",
Pos: pass.Fset.File(f.Pos()).Pos(err.Pos.Offset),
Message: "unchecked error",
Category: "errcheck",
})
}

Expand Down
29 changes: 29 additions & 0 deletions errcheck/analyzer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package errcheck

import (
"path/filepath"
"testing"

"golang.org/x/tools/go/analysis/analysistest"
)

func TestAnalyzer(t *testing.T) {
t.Run("default flags", func(t *testing.T) {
packageDir := filepath.Join(analysistest.TestData(), "src/a/")
_ = analysistest.Run(t, packageDir, Analyzer)
})

t.Run("check blanks", func(t *testing.T) {
packageDir := filepath.Join(analysistest.TestData(), "src/blank/")
_ = Analyzer.Flags.Set("blank", "true")
_ = analysistest.Run(t, packageDir, Analyzer)
_ = Analyzer.Flags.Set("blank", "false") // reset it
})

t.Run("check asserts", func(t *testing.T) {
packageDir := filepath.Join(analysistest.TestData(), "src/assert/")
_ = Analyzer.Flags.Set("assert", "true")
_ = analysistest.Run(t, packageDir, Analyzer)
_ = Analyzer.Flags.Set("assert", "false") // reset it
})
}
7 changes: 3 additions & 4 deletions errcheck/embedded_walker.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ func walkThroughEmbeddedInterfaces(sel *types.Selection) ([]types.Type, bool) {
// define the method, add it to our list, and loop.
namedInterfaceT, ok := getEmbeddedInterfaceDefiningMethod(interfaceT, fn)
if !ok {
// This should be impossible as long as we type-checked: either the
// interface or one of its embedded ones must implement the method...
panic(fmt.Sprintf("either %v or one of its embedded interfaces must implement %v", currentT, fn))
// Returned a nil interface, we are done.
break
}
result = append(result, namedInterfaceT)
interfaceT = namedInterfaceT.Underlying().(*types.Interface)
Expand All @@ -102,7 +101,7 @@ func getTypeAtFieldIndex(startingAt types.Type, fieldIndex int) types.Type {
func getEmbeddedInterfaceDefiningMethod(interfaceT *types.Interface, fn *types.Func) (*types.Named, bool) {
for i := 0; i < interfaceT.NumEmbeddeds(); i++ {
embedded := interfaceT.Embedded(i)
if definesMethod(embedded.Underlying().(*types.Interface), fn) {
if embedded != nil && definesMethod(embedded.Underlying().(*types.Interface), fn) {
return embedded, true
}
}
Expand Down
12 changes: 6 additions & 6 deletions errcheck/embedded_walker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ type testCase struct {

func TestWalkThroughEmbeddedInterfaces(t *testing.T) {
cases := []testCase{
testCase{"Inner{}.Method", false, nil},
testCase{"(&Inner{}).Method", false, nil},
testCase{"Outer{}.Method", false, nil},
testCase{"InnerInterface.Method", true, []string{"test.InnerInterface"}},
testCase{"OuterInterface.Method", true, []string{"test.OuterInterface", "test.InnerInterface"}},
testCase{"OuterInterfaceStruct.Method", true, []string{"test.OuterInterface", "test.InnerInterface"}},
{"Inner{}.Method", false, nil},
{"(&Inner{}).Method", false, nil},
{"Outer{}.Method", false, nil},
{"InnerInterface.Method", true, []string{"test.InnerInterface"}},
{"OuterInterface.Method", true, []string{"test.OuterInterface", "test.InnerInterface"}},
{"OuterInterfaceStruct.Method", true, []string{"test.OuterInterface", "test.InnerInterface"}},
}

for _, c := range cases {
Expand Down
Loading

0 comments on commit ad712ca

Please sign in to comment.