Compare commits
10 Commits
59562859b5
...
944e1d8441
Author | SHA1 | Date | |
---|---|---|---|
![]() |
944e1d8441 | ||
![]() |
b07c319f55 | ||
![]() |
31f2714643 | ||
![]() |
61f8c0e892 | ||
![]() |
9f4951f10d | ||
![]() |
10f281c1fd | ||
![]() |
1626fe46f0 | ||
![]() |
095e4952be | ||
![]() |
a86d8baa53 | ||
![]() |
094668e305 |
6
.github/workflows/pr.yml
vendored
6
.github/workflows/pr.yml
vendored
@ -39,11 +39,9 @@ jobs:
|
|||||||
# ex:
|
# ex:
|
||||||
# - 1.18beta1 -> 1.18.0-beta.1
|
# - 1.18beta1 -> 1.18.0-beta.1
|
||||||
# - 1.18rc1 -> 1.18.0-rc.1
|
# - 1.18rc1 -> 1.18.0-rc.1
|
||||||
# TODO(ldez) must be changed after the first release of golangci-lint with go1.23
|
go-version: ${{ env.GO_VERSION }}
|
||||||
# go-version: ${{ env.GO_VERSION }}
|
|
||||||
go-version: '1.22'
|
|
||||||
- name: lint
|
- name: lint
|
||||||
uses: golangci/golangci-lint-action@v6.1.0
|
uses: golangci/golangci-lint-action@v6.1.1
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
|
|
||||||
|
@ -890,6 +890,9 @@ linters-settings:
|
|||||||
# Detects input and output parameters that have a type of pointer to referential type.
|
# Detects input and output parameters that have a type of pointer to referential type.
|
||||||
# https://go-critic.com/overview.html#ptrToRefParam
|
# https://go-critic.com/overview.html#ptrToRefParam
|
||||||
- ptrToRefParam
|
- ptrToRefParam
|
||||||
|
# Detects append all its data while range it.
|
||||||
|
# https://go-critic.com/overview.html#rangeAppendAll
|
||||||
|
- rangeAppendAll
|
||||||
# Detects expensive copies of `for` loop range expressions.
|
# Detects expensive copies of `for` loop range expressions.
|
||||||
# https://go-critic.com/overview.html#rangeExprCopy
|
# https://go-critic.com/overview.html#rangeExprCopy
|
||||||
- rangeExprCopy
|
- rangeExprCopy
|
||||||
@ -1086,6 +1089,7 @@ linters-settings:
|
|||||||
- preferStringWriter
|
- preferStringWriter
|
||||||
- preferWriteByte
|
- preferWriteByte
|
||||||
- ptrToRefParam
|
- ptrToRefParam
|
||||||
|
- rangeAppendAll
|
||||||
- rangeExprCopy
|
- rangeExprCopy
|
||||||
- rangeValCopy
|
- rangeValCopy
|
||||||
- redundantSprint
|
- redundantSprint
|
||||||
@ -2115,14 +2119,17 @@ linters-settings:
|
|||||||
min-complexity: 4
|
min-complexity: 4
|
||||||
|
|
||||||
nilnil:
|
nilnil:
|
||||||
|
# In addition, detect opposite situation (simultaneous return of non-nil error and valid value).
|
||||||
|
# Default: false
|
||||||
|
detect-opposite: true
|
||||||
# List of return types to check.
|
# List of return types to check.
|
||||||
# Default: ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
|
# Default: ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
|
||||||
checked-types:
|
checked-types:
|
||||||
- ptr
|
- chan
|
||||||
- func
|
- func
|
||||||
- iface
|
- iface
|
||||||
- map
|
- map
|
||||||
- chan
|
- ptr
|
||||||
- uintptr
|
- uintptr
|
||||||
- unsafeptr
|
- unsafeptr
|
||||||
|
|
||||||
@ -3269,7 +3276,9 @@ linters-settings:
|
|||||||
- blank-import
|
- blank-import
|
||||||
- bool-compare
|
- bool-compare
|
||||||
- compares
|
- compares
|
||||||
|
- contains
|
||||||
- empty
|
- empty
|
||||||
|
- encoded-compare
|
||||||
- error-is-as
|
- error-is-as
|
||||||
- error-nil
|
- error-nil
|
||||||
- expected-actual
|
- expected-actual
|
||||||
@ -3279,6 +3288,7 @@ linters-settings:
|
|||||||
- len
|
- len
|
||||||
- negative-positive
|
- negative-positive
|
||||||
- nil-compare
|
- nil-compare
|
||||||
|
- regexp
|
||||||
- require-error
|
- require-error
|
||||||
- suite-broken-parallel
|
- suite-broken-parallel
|
||||||
- suite-dont-use-pkg
|
- suite-dont-use-pkg
|
||||||
@ -3292,15 +3302,17 @@ linters-settings:
|
|||||||
disable-all: true
|
disable-all: true
|
||||||
# Enable checkers by name
|
# Enable checkers by name
|
||||||
# (in addition to default
|
# (in addition to default
|
||||||
# blank-import, bool-compare, compares, empty, error-is-as, error-nil, expected-actual, go-require, float-compare,
|
# blank-import, bool-compare, compares, contains, empty, encoded-compare, error-is-as, error-nil, expected-actual,
|
||||||
# formatter, len, negative-positive, nil-compare, require-error, suite-broken-parallel, suite-dont-use-pkg,
|
# go-require, float-compare, formatter, len, negative-positive, nil-compare, regexp, require-error,
|
||||||
# suite-extra-assert-call, suite-subtest-run, useless-assert
|
# suite-broken-parallel, suite-dont-use-pkg, suite-extra-assert-call, suite-subtest-run, useless-assert
|
||||||
# ).
|
# ).
|
||||||
enable:
|
enable:
|
||||||
- blank-import
|
- blank-import
|
||||||
- bool-compare
|
- bool-compare
|
||||||
- compares
|
- compares
|
||||||
|
- contains
|
||||||
- empty
|
- empty
|
||||||
|
- encoded-compare
|
||||||
- error-is-as
|
- error-is-as
|
||||||
- error-nil
|
- error-nil
|
||||||
- expected-actual
|
- expected-actual
|
||||||
@ -3310,6 +3322,7 @@ linters-settings:
|
|||||||
- len
|
- len
|
||||||
- negative-positive
|
- negative-positive
|
||||||
- nil-compare
|
- nil-compare
|
||||||
|
- regexp
|
||||||
- require-error
|
- require-error
|
||||||
- suite-broken-parallel
|
- suite-broken-parallel
|
||||||
- suite-dont-use-pkg
|
- suite-dont-use-pkg
|
||||||
|
@ -132,31 +132,26 @@ Colored output:
|
|||||||
docker run -t --rm -v $(pwd):/app -w /app golangci/golangci-lint:{.LatestVersion} golangci-lint run -v
|
docker run -t --rm -v $(pwd):/app -w /app golangci/golangci-lint:{.LatestVersion} golangci-lint run -v
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install from Source
|
### Install from Sources
|
||||||
|
|
||||||
Note: such `go install`/`go get` installation aren't guaranteed to work. We recommend using binary installation.
|
Such `go install`/`go get` or "tools pattern" installations aren't guaranteed to work.
|
||||||
|
|
||||||
<details>
|
We recommend using binary installation.
|
||||||
<summary>Why?</summary>
|
|
||||||
|
|
||||||
`go install`/`go get` installation isn't recommended because of the following points:
|
Those installations aren't recommended because of the following points:
|
||||||
|
|
||||||
1. Some users use `-u` flag for `go get`, which upgrades our dependencies. Resulting configuration wasn't tested and isn't guaranteed to work.
|
1. Those installations are compiling golangci-lint locally, the Go version used to build will depend on your local Go version.
|
||||||
2. [`go.mod`](https://github.com/golangci/golangci-lint/blob/master/go.mod) replacement directive doesn't apply. It means a user will be using patched version of `golangci-lint` if we use such replacements.
|
2. Some users use `-u` flag for `go get`, which upgrades our dependencies. Resulting binary was not tested and is not guaranteed to work.
|
||||||
3. We've encountered a lot of issues with Go modules hashes.
|
3. When using "tools pattern", the dependencies of a tool can modify the dependencies of another. Resulting binary was not tested and is not guaranteed to work.
|
||||||
4. It allows installation from `master` branch which can't be considered stable.
|
4. We've encountered issues with Go modules hashes due to unexpected recreation of dependency tags.
|
||||||
5. It's slower than binary installation.
|
5. `go.mod` replacement directives don't apply transitively. It means a user will be using patched version of `golangci-lint` if we use such replacements.
|
||||||
|
6. It allows installation from main branch which can't be considered stable.
|
||||||
</details>
|
7. It's slower than binary installation.
|
||||||
|
|
||||||
<div style="margin-top: 2em;">
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go install github.com/golangci/golangci-lint/cmd/golangci-lint@{.LatestVersion}
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@{.LatestVersion}
|
||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
|
||||||
[Quick Start: how to use `golangci-lint`](/welcome/quick-start/).
|
[Quick Start: how to use `golangci-lint`](/welcome/quick-start/).
|
||||||
|
14
go.mod
14
go.mod
@ -6,10 +6,10 @@ require (
|
|||||||
4d63.com/gocheckcompilerdirectives v1.2.1
|
4d63.com/gocheckcompilerdirectives v1.2.1
|
||||||
4d63.com/gochecknoglobals v0.2.1
|
4d63.com/gochecknoglobals v0.2.1
|
||||||
github.com/4meepo/tagalign v1.3.4
|
github.com/4meepo/tagalign v1.3.4
|
||||||
github.com/Abirdcfly/dupword v0.1.1
|
github.com/Abirdcfly/dupword v0.1.3
|
||||||
github.com/Antonboom/errname v0.1.13
|
github.com/Antonboom/errname v1.0.0
|
||||||
github.com/Antonboom/nilnil v0.1.9
|
github.com/Antonboom/nilnil v1.0.0
|
||||||
github.com/Antonboom/testifylint v1.4.3
|
github.com/Antonboom/testifylint v1.5.0
|
||||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c
|
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c
|
||||||
github.com/Crocmagnon/fatcontext v0.5.2
|
github.com/Crocmagnon/fatcontext v0.5.2
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
|
||||||
@ -38,7 +38,7 @@ require (
|
|||||||
github.com/firefart/nonamedreturns v1.0.5
|
github.com/firefart/nonamedreturns v1.0.5
|
||||||
github.com/fzipp/gocyclo v0.6.0
|
github.com/fzipp/gocyclo v0.6.0
|
||||||
github.com/ghostiam/protogetter v0.3.8
|
github.com/ghostiam/protogetter v0.3.8
|
||||||
github.com/go-critic/go-critic v0.11.4
|
github.com/go-critic/go-critic v0.11.5
|
||||||
github.com/go-viper/mapstructure/v2 v2.2.1
|
github.com/go-viper/mapstructure/v2 v2.2.1
|
||||||
github.com/go-xmlfmt/xmlfmt v1.1.2
|
github.com/go-xmlfmt/xmlfmt v1.1.2
|
||||||
github.com/gofrs/flock v0.12.1
|
github.com/gofrs/flock v0.12.1
|
||||||
@ -126,7 +126,7 @@ require (
|
|||||||
go-simpler.org/sloglint v0.7.2
|
go-simpler.org/sloglint v0.7.2
|
||||||
go.uber.org/automaxprocs v1.6.0
|
go.uber.org/automaxprocs v1.6.0
|
||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
|
||||||
golang.org/x/tools v0.25.0
|
golang.org/x/tools v0.26.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
honnef.co/go/tools v0.5.1
|
honnef.co/go/tools v0.5.1
|
||||||
mvdan.cc/gofumpt v0.7.0
|
mvdan.cc/gofumpt v0.7.0
|
||||||
@ -192,7 +192,7 @@ require (
|
|||||||
golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect
|
golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect
|
||||||
golang.org/x/mod v0.21.0 // indirect
|
golang.org/x/mod v0.21.0 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
golang.org/x/sys v0.26.0 // indirect
|
||||||
golang.org/x/text v0.18.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
32
go.sum
generated
32
go.sum
generated
@ -37,14 +37,14 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
|||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8=
|
github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8=
|
||||||
github.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0=
|
github.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0=
|
||||||
github.com/Abirdcfly/dupword v0.1.1 h1:Bsxe0fIw6OwBtXMIncaTxCLHYO5BB+3mcsR5E8VXloY=
|
github.com/Abirdcfly/dupword v0.1.3 h1:9Pa1NuAsZvpFPi9Pqkd93I7LIYRURj+A//dFd5tgBeE=
|
||||||
github.com/Abirdcfly/dupword v0.1.1/go.mod h1:B49AcJdTYYkpd4HjgAcutNGG9HZ2JWwKunH9Y2BA6sM=
|
github.com/Abirdcfly/dupword v0.1.3/go.mod h1:8VbB2t7e10KRNdwTVoxdBaxla6avbhGzb8sCTygUMhw=
|
||||||
github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHOVvM=
|
github.com/Antonboom/errname v1.0.0 h1:oJOOWR07vS1kRusl6YRSlat7HFnb3mSfMl6sDMRoTBA=
|
||||||
github.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns=
|
github.com/Antonboom/errname v1.0.0/go.mod h1:gMOBFzK/vrTiXN9Oh+HFs+e6Ndl0eTFbtsRTSRdXyGI=
|
||||||
github.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ=
|
github.com/Antonboom/nilnil v1.0.0 h1:n+v+B12dsE5tbAqRODXmEKfZv9j2KcTBrp+LkoM4HZk=
|
||||||
github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ=
|
github.com/Antonboom/nilnil v1.0.0/go.mod h1:fDJ1FSFoLN6yoG65ANb1WihItf6qt9PJVTn/s2IrcII=
|
||||||
github.com/Antonboom/testifylint v1.4.3 h1:ohMt6AHuHgttaQ1xb6SSnxCeK4/rnK7KKzbvs7DmEck=
|
github.com/Antonboom/testifylint v1.5.0 h1:dlUIsDMtCrZWUnvkaCz3quJCoIjaGi41GzjPBGkkJ8A=
|
||||||
github.com/Antonboom/testifylint v1.4.3/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA=
|
github.com/Antonboom/testifylint v1.5.0/go.mod h1:wqaJbu0Blb5Wag2wv7Z5xt+CIV+eVLxtGZrlK13z3AE=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
|
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
|
||||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
@ -149,8 +149,8 @@ github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
|||||||
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
||||||
github.com/ghostiam/protogetter v0.3.8 h1:LYcXbYvybUyTIxN2Mj9h6rHrDZBDwZloPoKctWrFyJY=
|
github.com/ghostiam/protogetter v0.3.8 h1:LYcXbYvybUyTIxN2Mj9h6rHrDZBDwZloPoKctWrFyJY=
|
||||||
github.com/ghostiam/protogetter v0.3.8/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA=
|
github.com/ghostiam/protogetter v0.3.8/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA=
|
||||||
github.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU=
|
github.com/go-critic/go-critic v0.11.5 h1:TkDTOn5v7EEngMxu8KbuFqFR43USaaH8XRJLz1jhVYA=
|
||||||
github.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc=
|
github.com/go-critic/go-critic v0.11.5/go.mod h1:wu6U7ny9PiaHaZHcvMDmdysMqvDem162Rh3zWTrqk8M=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
@ -697,8 +697,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
|||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -777,8 +777,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@ -860,8 +860,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
|||||||
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
||||||
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
|
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
|
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
||||||
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
|
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
"preferStringWriter",
|
"preferStringWriter",
|
||||||
"preferWriteByte",
|
"preferWriteByte",
|
||||||
"ptrToRefParam",
|
"ptrToRefParam",
|
||||||
|
"rangeAppendAll",
|
||||||
"rangeExprCopy",
|
"rangeExprCopy",
|
||||||
"rangeValCopy",
|
"rangeValCopy",
|
||||||
"redundantSprint",
|
"redundantSprint",
|
||||||
@ -2188,13 +2189,18 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"detect-opposite": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"checked-types": {
|
"checked-types": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"description": "List of return types to check.",
|
"description": "List of return types to check.",
|
||||||
"items": {
|
"items": {
|
||||||
"enum": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
|
"enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
|
||||||
},
|
},
|
||||||
"default": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
|
"default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2905,7 +2911,9 @@
|
|||||||
"blank-import",
|
"blank-import",
|
||||||
"bool-compare",
|
"bool-compare",
|
||||||
"compares",
|
"compares",
|
||||||
|
"contains",
|
||||||
"empty",
|
"empty",
|
||||||
|
"encoded-compare",
|
||||||
"error-is-as",
|
"error-is-as",
|
||||||
"error-nil",
|
"error-nil",
|
||||||
"expected-actual",
|
"expected-actual",
|
||||||
@ -2915,6 +2923,7 @@
|
|||||||
"len",
|
"len",
|
||||||
"negative-positive",
|
"negative-positive",
|
||||||
"nil-compare",
|
"nil-compare",
|
||||||
|
"regexp",
|
||||||
"require-error",
|
"require-error",
|
||||||
"suite-broken-parallel",
|
"suite-broken-parallel",
|
||||||
"suite-dont-use-pkg",
|
"suite-dont-use-pkg",
|
||||||
@ -2928,16 +2937,19 @@
|
|||||||
"blank-import",
|
"blank-import",
|
||||||
"bool-compare",
|
"bool-compare",
|
||||||
"compares",
|
"compares",
|
||||||
|
"contains",
|
||||||
"empty",
|
"empty",
|
||||||
|
"encoded-compare",
|
||||||
"error-is-as",
|
"error-is-as",
|
||||||
"error-nil",
|
"error-nil",
|
||||||
"expected-actual",
|
"expected-actual",
|
||||||
"float-compare",
|
"float-compare",
|
||||||
"float-compare",
|
"formatter",
|
||||||
"go-require",
|
"go-require",
|
||||||
"len",
|
"len",
|
||||||
"negative-positive",
|
"negative-positive",
|
||||||
"nil-compare",
|
"nil-compare",
|
||||||
|
"regexp",
|
||||||
"require-error",
|
"require-error",
|
||||||
"suite-broken-parallel",
|
"suite-broken-parallel",
|
||||||
"suite-dont-use-pkg",
|
"suite-dont-use-pkg",
|
||||||
@ -2954,7 +2966,9 @@
|
|||||||
"blank-import",
|
"blank-import",
|
||||||
"bool-compare",
|
"bool-compare",
|
||||||
"compares",
|
"compares",
|
||||||
|
"contains",
|
||||||
"empty",
|
"empty",
|
||||||
|
"encoded-compare",
|
||||||
"error-is-as",
|
"error-is-as",
|
||||||
"error-nil",
|
"error-nil",
|
||||||
"expected-actual",
|
"expected-actual",
|
||||||
@ -2964,6 +2978,7 @@
|
|||||||
"len",
|
"len",
|
||||||
"negative-positive",
|
"negative-positive",
|
||||||
"nil-compare",
|
"nil-compare",
|
||||||
|
"regexp",
|
||||||
"require-error",
|
"require-error",
|
||||||
"suite-broken-parallel",
|
"suite-broken-parallel",
|
||||||
"suite-dont-use-pkg",
|
"suite-dont-use-pkg",
|
||||||
|
@ -733,7 +733,8 @@ type NestifSettings struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NilNilSettings struct {
|
type NilNilSettings struct {
|
||||||
CheckedTypes []string `mapstructure:"checked-types"`
|
DetectOpposite bool `mapstructure:"detect-opposite"`
|
||||||
|
CheckedTypes []string `mapstructure:"checked-types"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NlreturnSettings struct {
|
type NlreturnSettings struct {
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
"go/build"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/scanner"
|
"go/scanner"
|
||||||
"go/types"
|
"go/types"
|
||||||
@ -164,6 +165,7 @@ func (lp *loadingPackage) loadFromSource(loadMode LoadMode) error {
|
|||||||
pkg.Errors = append(pkg.Errors, lp.convertError(err)...)
|
pkg.Errors = append(pkg.Errors, lp.convertError(err)...)
|
||||||
},
|
},
|
||||||
GoVersion: rv, // TODO(ldez) temporary workaround
|
GoVersion: rv, // TODO(ldez) temporary workaround
|
||||||
|
Sizes: types.SizesFor(build.Default.Compiler, build.Default.GOARCH),
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax)
|
_ = types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax)
|
||||||
|
22
pkg/golinters/errname/testdata/errname.go
vendored
22
pkg/golinters/errname/testdata/errname.go
vendored
@ -11,11 +11,11 @@ var (
|
|||||||
ErrEndOfFile = errors.New("end of file")
|
ErrEndOfFile = errors.New("end of file")
|
||||||
errEndOfFile = errors.New("end of file")
|
errEndOfFile = errors.New("end of file")
|
||||||
|
|
||||||
EndOfFileError = errors.New("end of file") // want "the variable name `EndOfFileError` should conform to the `ErrXxx` format"
|
EndOfFileError = errors.New("end of file") // want "the sentinel error name `EndOfFileError` should conform to the `ErrXxx` format"
|
||||||
ErrorEndOfFile = errors.New("end of file") // want "the variable name `ErrorEndOfFile` should conform to the `ErrXxx` format"
|
ErrorEndOfFile = errors.New("end of file") // want "the sentinel error name `ErrorEndOfFile` should conform to the `ErrXxx` format"
|
||||||
EndOfFileErr = errors.New("end of file") // want "the variable name `EndOfFileErr` should conform to the `ErrXxx` format"
|
EndOfFileErr = errors.New("end of file") // want "the sentinel error name `EndOfFileErr` should conform to the `ErrXxx` format"
|
||||||
endOfFileError = errors.New("end of file") // want "the variable name `endOfFileError` should conform to the `errXxx` format"
|
endOfFileError = errors.New("end of file") // want "the sentinel error name `endOfFileError` should conform to the `errXxx` format"
|
||||||
errorEndOfFile = errors.New("end of file") // want "the variable name `errorEndOfFile` should conform to the `errXxx` format"
|
errorEndOfFile = errors.New("end of file") // want "the sentinel error name `errorEndOfFile` should conform to the `errXxx` format"
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxSize = 256
|
const maxSize = 256
|
||||||
@ -24,8 +24,8 @@ var (
|
|||||||
ErrOutOfSize = fmt.Errorf("out of size (max %d)", maxSize)
|
ErrOutOfSize = fmt.Errorf("out of size (max %d)", maxSize)
|
||||||
errOutOfSize = fmt.Errorf("out of size (max %d)", maxSize)
|
errOutOfSize = fmt.Errorf("out of size (max %d)", maxSize)
|
||||||
|
|
||||||
OutOfSizeError = fmt.Errorf("out of size (max %d)", maxSize) // want "the variable name `OutOfSizeError` should conform to the `ErrXxx` format"
|
OutOfSizeError = fmt.Errorf("out of size (max %d)", maxSize) // want "the sentinel error name `OutOfSizeError` should conform to the `ErrXxx` format"
|
||||||
outOfSizeError = fmt.Errorf("out of size (max %d)", maxSize) // want "the variable name `outOfSizeError` should conform to the `errXxx` format"
|
outOfSizeError = fmt.Errorf("out of size (max %d)", maxSize) // want "the sentinel error name `outOfSizeError` should conform to the `errXxx` format"
|
||||||
)
|
)
|
||||||
|
|
||||||
func errInsideFuncIsNotSentinel() error {
|
func errInsideFuncIsNotSentinel() error {
|
||||||
@ -42,14 +42,14 @@ type DNSConfigError struct{}
|
|||||||
|
|
||||||
func (D DNSConfigError) Error() string { return "DNS config error" }
|
func (D DNSConfigError) Error() string { return "DNS config error" }
|
||||||
|
|
||||||
type someTypeWithoutPtr struct{} // want "the type name `someTypeWithoutPtr` should conform to the `xxxError` format"
|
type someTypeWithoutPtr struct{} // want "the error type name `someTypeWithoutPtr` should conform to the `xxxError` format"
|
||||||
func (s someTypeWithoutPtr) Error() string { return "someTypeWithoutPtr" }
|
func (s someTypeWithoutPtr) Error() string { return "someTypeWithoutPtr" }
|
||||||
|
|
||||||
type SomeTypeWithoutPtr struct{} // want "the type name `SomeTypeWithoutPtr` should conform to the `XxxError` format"
|
type SomeTypeWithoutPtr struct{} // want "the error type name `SomeTypeWithoutPtr` should conform to the `XxxError` format"
|
||||||
func (s SomeTypeWithoutPtr) Error() string { return "SomeTypeWithoutPtr" }
|
func (s SomeTypeWithoutPtr) Error() string { return "SomeTypeWithoutPtr" }
|
||||||
|
|
||||||
type someTypeWithPtr struct{} // want "the type name `someTypeWithPtr` should conform to the `xxxError` format"
|
type someTypeWithPtr struct{} // want "the error type name `someTypeWithPtr` should conform to the `xxxError` format"
|
||||||
func (s *someTypeWithPtr) Error() string { return "someTypeWithPtr" }
|
func (s *someTypeWithPtr) Error() string { return "someTypeWithPtr" }
|
||||||
|
|
||||||
type SomeTypeWithPtr struct{} // want "the type name `SomeTypeWithPtr` should conform to the `XxxError` format"
|
type SomeTypeWithPtr struct{} // want "the error type name `SomeTypeWithPtr` should conform to the `XxxError` format"
|
||||||
func (s *SomeTypeWithPtr) Error() string { return "SomeTypeWithPtr" }
|
func (s *SomeTypeWithPtr) Error() string { return "SomeTypeWithPtr" }
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package nilnil
|
package nilnil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/Antonboom/nilnil/pkg/analyzer"
|
"github.com/Antonboom/nilnil/pkg/analyzer"
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
|
|
||||||
@ -10,13 +8,16 @@ import (
|
|||||||
"github.com/golangci/golangci-lint/pkg/goanalysis"
|
"github.com/golangci/golangci-lint/pkg/goanalysis"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(cfg *config.NilNilSettings) *goanalysis.Linter {
|
func New(settings *config.NilNilSettings) *goanalysis.Linter {
|
||||||
a := analyzer.New()
|
a := analyzer.New()
|
||||||
|
|
||||||
cfgMap := make(map[string]map[string]any)
|
cfgMap := make(map[string]map[string]any)
|
||||||
if cfg != nil && len(cfg.CheckedTypes) != 0 {
|
if settings != nil {
|
||||||
cfgMap[a.Name] = map[string]any{
|
cfgMap[a.Name] = map[string]any{
|
||||||
"checked-types": strings.Join(cfg.CheckedTypes, ","),
|
"detect-opposite": settings.DetectOpposite,
|
||||||
|
}
|
||||||
|
if len(settings.CheckedTypes) != 0 {
|
||||||
|
cfgMap[a.Name]["checked-types"] = settings.CheckedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
139
pkg/golinters/nilnil/testdata/nilnil.go
vendored
139
pkg/golinters/nilnil/testdata/nilnil.go
vendored
@ -3,8 +3,11 @@ package testdata
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"go/token"
|
"go/token"
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -13,100 +16,100 @@ import (
|
|||||||
type User struct{}
|
type User struct{}
|
||||||
|
|
||||||
func primitivePtr() (*int, error) {
|
func primitivePtr() (*int, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func structPtr() (*User, error) {
|
func structPtr() (*User, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func emptyStructPtr() (*struct{}, error) {
|
func emptyStructPtr() (*struct{}, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func anonymousStructPtr() (*struct{ ID string }, error) {
|
func anonymousStructPtr() (*struct{ ID string }, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func unsafePtr() (unsafe.Pointer, error) {
|
func unsafePtr() (unsafe.Pointer, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func uintPtr() (uintptr, error) {
|
func uintPtr() (uintptr, error) {
|
||||||
return 0, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return 0, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func uintPtr0b() (uintptr, error) {
|
func uintPtr0b() (uintptr, error) {
|
||||||
return 0b0, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return 0b0, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func uintPtr0x() (uintptr, error) {
|
func uintPtr0x() (uintptr, error) {
|
||||||
return 0x00, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return 0x00, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func uintPtr0o() (uintptr, error) {
|
func uintPtr0o() (uintptr, error) {
|
||||||
return 0o000, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return 0o000, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func chBi() (chan int, error) {
|
func chBi() (chan int, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func chIn() (chan<- int, error) {
|
func chIn() (chan<- int, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func chOut() (<-chan int, error) {
|
func chOut() (<-chan int, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func fun() (func(), error) {
|
func fun() (func(), error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func funWithArgsAndResults() (func(a, b, c int) (int, int), error) {
|
func funWithArgsAndResults() (func(a, b, c int) (int, int), error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func iface() (interface{}, error) {
|
func iface() (interface{}, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func anyType() (any, error) {
|
func anyType() (any, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func m1() (map[int]int, error) {
|
func m1() (map[int]int, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func m2() (map[int]*User, error) {
|
func m2() (map[int]*User, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
type mapAlias = map[int]*User
|
type mapAlias = map[int]*User
|
||||||
|
|
||||||
func m3() (mapAlias, error) {
|
func m3() (mapAlias, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
type Storage struct{}
|
type Storage struct{}
|
||||||
|
|
||||||
func (s *Storage) GetUser() (*User, error) {
|
func (s *Storage) GetUser() (*User, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ifReturn() (*User, error) {
|
func ifReturn() (*User, error) {
|
||||||
var s Storage
|
var s Storage
|
||||||
if _, err := s.GetUser(); err != nil {
|
if _, err := s.GetUser(); err != nil {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
return new(User), nil
|
return new(User), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func forReturn() (*User, error) {
|
func forReturn() (*User, error) {
|
||||||
for {
|
for {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,15 +117,15 @@ func multipleReturn() (*User, error) {
|
|||||||
var s Storage
|
var s Storage
|
||||||
|
|
||||||
if _, err := s.GetUser(); err != nil {
|
if _, err := s.GetUser(); err != nil {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := s.GetUser(); err != nil {
|
if _, err := s.GetUser(); err != nil {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := s.GetUser(); err != nil {
|
if _, err := s.GetUser(); err != nil {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
return new(User), nil
|
return new(User), nil
|
||||||
@ -130,11 +133,11 @@ func multipleReturn() (*User, error) {
|
|||||||
|
|
||||||
func nested() {
|
func nested() {
|
||||||
_ = func() (*User, error) {
|
_ = func() (*User, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = func() (*User, error) {
|
_, _ = func() (*User, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +148,7 @@ func deeplyNested() {
|
|||||||
_ = func() (*User, error) {
|
_ = func() (*User, error) {
|
||||||
_ = func() {}
|
_ = func() {}
|
||||||
_ = func() int { return 0 }
|
_ = func() int { return 0 }
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
@ -159,31 +162,31 @@ type MyError interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func myError() (*User, MyError) {
|
func myError() (*User, MyError) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types.
|
// Types.
|
||||||
|
|
||||||
func structPtrTypeExtPkg() (*os.File, error) {
|
func structPtrTypeExtPkg() (*os.File, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func primitivePtrTypeExtPkg() (*token.Token, error) {
|
func primitivePtrTypeExtPkg() (*token.Token, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcTypeExtPkg() (http.HandlerFunc, error) {
|
func funcTypeExtPkg() (http.HandlerFunc, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ifaceTypeExtPkg() (io.Closer, error) {
|
func ifaceTypeExtPkg() (io.Closer, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
type closerAlias = io.Closer
|
type closerAlias = io.Closer
|
||||||
|
|
||||||
func ifaceTypeAliasedExtPkg() (closerAlias, error) {
|
func ifaceTypeAliasedExtPkg() (closerAlias, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -195,29 +198,29 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func structPtrType() (StructPtrType, error) {
|
func structPtrType() (StructPtrType, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func primitivePtrType() (PrimitivePtrType, error) {
|
func primitivePtrType() (PrimitivePtrType, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func channelType() (ChannelType, error) {
|
func channelType() (ChannelType, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcType() (FuncType, error) {
|
func funcType() (FuncType, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ifaceType() (Checker, error) {
|
func ifaceType() (Checker, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
type checkerAlias = Checker
|
type checkerAlias = Checker
|
||||||
|
|
||||||
func ifaceTypeAliased() (checkerAlias, error) {
|
func ifaceTypeAliased() (checkerAlias, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -226,7 +229,7 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func ptrIntegerType() (PtrIntegerType, error) {
|
func ptrIntegerType() (PtrIntegerType, error) {
|
||||||
return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead"
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not checked at all.
|
// Not checked at all.
|
||||||
@ -317,3 +320,57 @@ func implicitNil3() (*User, error) {
|
|||||||
return nil, wrap(nil)
|
return nil, wrap(nil)
|
||||||
}
|
}
|
||||||
func wrap(err error) error { return err }
|
func wrap(err error) error { return err }
|
||||||
|
|
||||||
|
// Opposite.
|
||||||
|
|
||||||
|
func primitivePtrTypeOpposite() (*int, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return new(int), errors.New("validation failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPtrTypeOpposite() (*User, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return new(User), fmt.Errorf("invalid %v", 42)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unsafePtrOpposite() (unsafe.Pointer, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
var i int
|
||||||
|
return unsafe.Pointer(&i), io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
func uintPtrOpposite() (uintptr, error) {
|
||||||
|
if false {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
return 0xc82000c290, wrap(io.EOF)
|
||||||
|
}
|
||||||
|
|
||||||
|
func channelTypeOpposite() (ChannelType, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return make(ChannelType), fmt.Errorf("wrapped: %w", io.EOF)
|
||||||
|
}
|
||||||
|
|
||||||
|
func funcTypeOpposite() (FuncType, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return func(i int) int {
|
||||||
|
return 0
|
||||||
|
}, errors.New("no func type, please")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ifaceTypeOpposite() (io.Reader, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return new(bytes.Buffer), new(net.AddrError)
|
||||||
|
}
|
||||||
|
83
pkg/golinters/nilnil/testdata/nilnil_detect_opposite.go
vendored
Normal file
83
pkg/golinters/nilnil/testdata/nilnil_detect_opposite.go
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
//golangcitest:args -Enilnil
|
||||||
|
//golangcitest:config_path testdata/nilnil_detect_opposite.yml
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func primitivePtrTypeOpposite() (*int, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return new(int), errors.New("validation failed") // want "return both a non-nil error and a valid value: use separate returns instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPtrTypeOpposite() (*User, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return new(User), fmt.Errorf("invalid %v", 42) // want "return both a non-nil error and a valid value: use separate returns instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func unsafePtrOpposite() (unsafe.Pointer, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
var i int
|
||||||
|
return unsafe.Pointer(&i), io.EOF // want "return both a non-nil error and a valid value: use separate returns instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func uintPtrOpposite() (uintptr, error) {
|
||||||
|
if false {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
return 0xc82000c290, wrap(io.EOF) // want "return both a non-nil error and a valid value: use separate returns instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func channelTypeOpposite() (ChannelType, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return make(ChannelType), fmt.Errorf("wrapped: %w", io.EOF) // want "return both a non-nil error and a valid value: use separate returns instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func funcTypeOpposite() (FuncType, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return func(i int) int { // want "return both a non-nil error and a valid value: use separate returns instead"
|
||||||
|
return 0
|
||||||
|
}, errors.New("no func type, please")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ifaceTypeOpposite() (io.Reader, error) {
|
||||||
|
if false {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
return new(bytes.Buffer), new(net.AddrError) // want "return both a non-nil error and a valid value: use separate returns instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
User struct{}
|
||||||
|
StructPtrType *User
|
||||||
|
PrimitivePtrType *int
|
||||||
|
ChannelType chan int
|
||||||
|
FuncType func(int) int
|
||||||
|
Checker interface{ Check() }
|
||||||
|
)
|
||||||
|
|
||||||
|
func wrap(err error) error { return err }
|
||||||
|
|
||||||
|
func structPtr() (*int, error) {
|
||||||
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPtrValid() (*int, error) {
|
||||||
|
return new(int), nil
|
||||||
|
}
|
3
pkg/golinters/nilnil/testdata/nilnil_detect_opposite.yml
vendored
Normal file
3
pkg/golinters/nilnil/testdata/nilnil_detect_opposite.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
linters-settings:
|
||||||
|
nilnil:
|
||||||
|
detect-opposite: true
|
39
pkg/golinters/nilnil/testdata/nilnil_pointers_only.go
vendored
Normal file
39
pkg/golinters/nilnil/testdata/nilnil_pointers_only.go
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//golangcitest:args -Enilnil
|
||||||
|
//golangcitest:config_path testdata/nilnil_pointers_only.yml
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
type User struct{}
|
||||||
|
|
||||||
|
func primitivePtr() (*int, error) {
|
||||||
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPtr() (*User, error) {
|
||||||
|
return nil, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func unsafePtr() (unsafe.Pointer, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func uintPtr0o() (uintptr, error) {
|
||||||
|
return 0o000, nil // want "return both a `nil` error and an invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func chBi() (chan int, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fun() (func(), error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func anyType() (any, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func m1() (map[int]int, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
5
pkg/golinters/nilnil/testdata/nilnil_pointers_only.yml
vendored
Normal file
5
pkg/golinters/nilnil/testdata/nilnil_pointers_only.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
linters-settings:
|
||||||
|
nilnil:
|
||||||
|
checked-types:
|
||||||
|
- ptr
|
||||||
|
- uintptr
|
@ -225,5 +225,5 @@ func TestPrinter_Print_multiple(t *testing.T) {
|
|||||||
goldenJSON, err := os.ReadFile(filepath.Join("testdata", "golden-json.json"))
|
goldenJSON, err := os.ReadFile(filepath.Join("testdata", "golden-json.json"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, string(goldenJSON), stdOutBuffer.String())
|
assert.JSONEq(t, string(goldenJSON), stdOutBuffer.String())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user