aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/ykadowak
diff options
context:
space:
mode:
authordependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2024-03-04 17:40:11 +0000
committerTaras Madan <tarasmadan@google.com>2024-03-04 18:34:55 +0000
commit5fc5366972c874b919f93165bb4ed4e2bcb7c350 (patch)
tree287c3361a0dee0c72af80d9a1a66714a06e98a62 /vendor/github.com/ykadowak
parent1be5ce38a9059c356eb193a8c34d60d61c9fc31f (diff)
mod: bump github.com/golangci/golangci-lint from 1.55.2 to 1.56.2
Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.55.2 to 1.56.2. - [Release notes](https://github.com/golangci/golangci-lint/releases) - [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md) - [Commits](https://github.com/golangci/golangci-lint/compare/v1.55.2...v1.56.2) --- updated-dependencies: - dependency-name: github.com/golangci/golangci-lint dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Diffstat (limited to 'vendor/github.com/ykadowak')
-rw-r--r--vendor/github.com/ykadowak/zerologlint/.goreleaser.yaml7
-rw-r--r--vendor/github.com/ykadowak/zerologlint/zerologlint.go102
2 files changed, 82 insertions, 27 deletions
diff --git a/vendor/github.com/ykadowak/zerologlint/.goreleaser.yaml b/vendor/github.com/ykadowak/zerologlint/.goreleaser.yaml
index c1b23f00e..f3af3f212 100644
--- a/vendor/github.com/ykadowak/zerologlint/.goreleaser.yaml
+++ b/vendor/github.com/ykadowak/zerologlint/.goreleaser.yaml
@@ -11,13 +11,6 @@ builds:
- linux
- windows
- darwin
-archives:
- - replacements:
- darwin: Darwin
- linux: Linux
- windows: Windows
- 386: i386
- amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
diff --git a/vendor/github.com/ykadowak/zerologlint/zerologlint.go b/vendor/github.com/ykadowak/zerologlint/zerologlint.go
index bec50e52b..8c8fb74fc 100644
--- a/vendor/github.com/ykadowak/zerologlint/zerologlint.go
+++ b/vendor/github.com/ykadowak/zerologlint/zerologlint.go
@@ -13,8 +13,8 @@ import (
)
var Analyzer = &analysis.Analyzer{
- Name: "zerologlinter",
- Doc: "finds cases where zerolog methods are not followed by Msg or Send",
+ Name: "zerologlint",
+ Doc: "Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg`",
Run: run,
Requires: []*analysis.Analyzer{
buildssa.Analyzer,
@@ -26,42 +26,65 @@ type posser interface {
Pos() token.Pos
}
-// posser is an interface just to hold both ssa.Call and ssa.Defer in our set
+// callDefer is an interface just to hold both ssa.Call and ssa.Defer in our set
type callDefer interface {
Common() *ssa.CallCommon
Pos() token.Pos
}
-func run(pass *analysis.Pass) (interface{}, error) {
- srcFuncs := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs
-
- // This set holds all the ssa block that is a zerolog.Event type instance
+type linter struct {
+ // eventSet holds all the ssa block that is a zerolog.Event type instance
// that should be dispatched.
// Everytime the zerolog.Event is dispatched with Msg() or Send(),
// deletes that block from this set.
// At the end, check if the set is empty, or report the not dispatched block.
- set := make(map[posser]struct{})
+ eventSet map[posser]struct{}
+ // deleteLater holds the ssa block that should be deleted from eventSet after
+ // all the inspection is done.
+ // this is required because `else` ssa block comes after the dispatch of `if`` block.
+ // e.g., if err != nil { log.Error() } else { log.Info() } log.Send()
+ // deleteLater takes care of the log.Info() block.
+ deleteLater map[posser]struct{}
+ recLimit uint
+}
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ srcFuncs := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs
+
+ l := &linter{
+ eventSet: make(map[posser]struct{}),
+ deleteLater: make(map[posser]struct{}),
+ recLimit: 100,
+ }
for _, sf := range srcFuncs {
for _, b := range sf.Blocks {
for _, instr := range b.Instrs {
if c, ok := instr.(*ssa.Call); ok {
- inspect(c, &set)
+ l.inspect(c)
} else if c, ok := instr.(*ssa.Defer); ok {
- inspect(c, &set)
+ l.inspect(c)
}
}
}
}
+
+ // apply deleteLater to envetSet for else branches of if-else cases
+
+ for k := range l.deleteLater {
+ delete(l.eventSet, k)
+ }
+
// At the end, if the set is clear -> ok.
- // Otherwise, there must be a left zerolog.Event var that weren't dispached. So report it.
- for k := range set {
+ // Otherwise, there must be a left zerolog.Event var that weren't dispatched. So report it.
+ for k := range l.eventSet {
pass.Reportf(k.Pos(), "must be dispatched by Msg or Send method")
}
+
return nil, nil
}
-func inspect(cd callDefer, set *map[posser]struct{}) {
+func (l *linter) inspect(cd callDefer) {
c := cd.Common()
// check if it's in github.com/rs/zerolog/log since there's some
@@ -70,7 +93,7 @@ func inspect(cd callDefer, set *map[posser]struct{}) {
if isInLogPkg(*c) || isLoggerRecv(*c) {
if isZerologEvent(c.Value) {
// this ssa block should be dispatched afterwards at some point
- (*set)[cd] = struct{}{}
+ l.eventSet[cd] = struct{}{}
return
}
}
@@ -88,7 +111,7 @@ func inspect(cd callDefer, set *map[posser]struct{}) {
for _, p := range f.Params {
if isZerologEvent(p) {
// check if this zerolog.Event as a parameter is dispatched in the function
- // TODO: specifically, it can be dispatched in another function that is called in this function, and
+ // TODO: technically, it can be dispatched in another function that is called in this function, and
// this algorithm cannot track that. But I'm tired of thinking about that for now.
for _, b := range f.Blocks {
for _, instr := range b.Instrs {
@@ -96,10 +119,12 @@ func inspect(cd callDefer, set *map[posser]struct{}) {
case *ssa.Call:
if inspectDispatchInFunction(v.Common()) {
shouldReturn = false
+ break
}
case *ssa.Defer:
if inspectDispatchInFunction(v.Common()) {
shouldReturn = false
+ break
}
}
}
@@ -112,19 +137,56 @@ func inspect(cd callDefer, set *map[posser]struct{}) {
}
for _, arg := range c.Args {
if isZerologEvent(arg) {
- val := getRootSsaValue(arg)
- // if there's branch, remove both ways from the set
- if phi, ok := val.(*ssa.Phi); ok {
+ // if there's branch, track both ways
+ // this is for the case like:
+ // logger := log.Info()
+ // if err != nil {
+ // logger = log.Error()
+ // }
+ // logger.Send()
+ //
+ // Similar case like below goes to the same root but that doesn't
+ // have any side effect.
+ // logger := log.Info()
+ // if err != nil {
+ // logger = logger.Str("a", "b")
+ // }
+ // logger.Send()
+ if phi, ok := arg.(*ssa.Phi); ok {
for _, edge := range phi.Edges {
- delete(*set, edge)
+ l.dfsEdge(edge, make(map[ssa.Value]struct{}), 0)
}
} else {
- delete(*set, val)
+ val := getRootSsaValue(arg)
+ delete(l.eventSet, val)
}
}
}
}
+func (l *linter) dfsEdge(v ssa.Value, visit map[ssa.Value]struct{}, cnt uint) {
+ // only for safety
+ if cnt > l.recLimit {
+ return
+ }
+ cnt++
+
+ if _, ok := visit[v]; ok {
+ return
+ }
+ visit[v] = struct{}{}
+
+ val := getRootSsaValue(v)
+ phi, ok := val.(*ssa.Phi)
+ if !ok {
+ l.deleteLater[val] = struct{}{}
+ return
+ }
+ for _, edge := range phi.Edges {
+ l.dfsEdge(edge, visit, cnt)
+ }
+}
+
func inspectDispatchInFunction(cc *ssa.CallCommon) bool {
if isDispatchMethod(cc.StaticCallee()) {
for _, arg := range cc.Args {