diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6558fd5..f6b934e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -11,7 +11,9 @@ jobs: strategy: matrix: go-versions: - - "1.22" + - "1.23" + - "1.24" + - "1.25" runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 002f89b..76c1561 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -13,13 +13,12 @@ jobs: name: lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-go@v6 with: - go-version: '1.22' + go-version: '1.25' cache: false - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v9 with: - version: v1.58.1 - + version: v2.6 diff --git a/go.mod b/go.mod index c7afb79..e166a7a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module sigs.k8s.io/logtools -go 1.22.0 +go 1.23.0 require ( github.com/golangci/plugin-module-register v0.1.1 diff --git a/logcheck/pkg/filter.go b/logcheck/pkg/filter.go index e0bed11..a24a553 100644 --- a/logcheck/pkg/filter.go +++ b/logcheck/pkg/filter.go @@ -50,7 +50,9 @@ func (f *RegexpFilter) Set(filename string) error { if err != nil { return err } - defer file.Close() + defer func() { + _ = file.Close() + }() return f.Parse(file, filename) } diff --git a/logcheck/pkg/logcheck.go b/logcheck/pkg/logcheck.go index 2a1453c..9d553c3 100644 --- a/logcheck/pkg/logcheck.go +++ b/logcheck/pkg/logcheck.go @@ -324,7 +324,7 @@ func checkForFunctionExpr(fexpr *ast.CallExpr, pass *analysis.Pass, c *Config) { // the result of klog.V). func isKlogVerbose(expr ast.Expr, pass *analysis.Pass) bool { if typeAndValue, ok := pass.TypesInfo.Types[expr]; ok { - switch t := typeAndValue.Type.(type) { + switch t := unwrapAlias(typeAndValue.Type).(type) { case *types.Named: if typeName := t.Obj(); typeName != nil { if pkg := typeName.Pkg(); pkg != nil { @@ -371,7 +371,7 @@ func isPackage(expr ast.Expr, packagePath string, pass *analysis.Pass) bool { // isGoLogger checks whether an expression is logr.Logger. func isGoLogger(expr ast.Expr, pass *analysis.Pass) bool { if typeAndValue, ok := pass.TypesInfo.Types[expr]; ok { - switch t := typeAndValue.Type.(type) { + switch t := unwrapAlias(typeAndValue.Type).(type) { case *types.Named: if typeName := t.Obj(); typeName != nil { if pkg := typeName.Pkg(); pkg != nil { @@ -500,7 +500,7 @@ func checkForContextAndLogger(n ast.Node, params *ast.FieldList, pass *analysis. for _, param := range params.List { if typeAndValue, ok := pass.TypesInfo.Types[param.Type]; ok { - switch t := typeAndValue.Type.(type) { + switch t := unwrapAlias(typeAndValue.Type).(type) { case *types.Named: if typeName := t.Obj(); typeName != nil { if pkg := typeName.Pkg(); pkg != nil { @@ -796,6 +796,15 @@ func checkForComments(object types.Object, doc *ast.CommentGroup, pass *analysis } } +func unwrapAlias(t types.Type) types.Type { + switch t := t.(type) { + case *types.Alias: + return unwrapAlias(t.Rhs()) + default: + return t + } +} + const ( logcheckPrefix = "//logcheck:" contextKeyword = "context" diff --git a/logcheck/testdata/src/parameters/parameters.go b/logcheck/testdata/src/parameters/parameters.go index 999a212..8a8fae0 100644 --- a/logcheck/testdata/src/parameters/parameters.go +++ b/logcheck/testdata/src/parameters/parameters.go @@ -24,10 +24,14 @@ import ( "context" "fmt" + "github.com/go-logr/logr" klog "k8s.io/klog/v2" ) func parameterCalls() { + logger := klog.FromContext(context.Background()) // Result is a type alias. + logger2 := logr.Logger(logger) // Not a type alias. + // format strings (incomplete list...) klog.Infof("%d", 1) klog.InfoS("%d", 1) // want `logging function "InfoS" should not use format specifier "%d"` @@ -45,14 +49,26 @@ func parameterCalls() { klog.InfoS("hello", "value", fmt.Sprintf("%d", 1)) // odd number of parameters - klog.InfoS("hello", "key") // want `Additional arguments to InfoS should always be Key Value pairs. Please check if there is any key or value missing.` - klog.ErrorS(nil, "hello", "key") // want `Additional arguments to ErrorS should always be Key Value pairs. Please check if there is any key or value missing.` + klog.InfoS("hello", "key") // want `Additional arguments to InfoS should always be Key Value pairs. Please check if there is any key or value missing.` + klog.ErrorS(nil, "hello", "key") // want `Additional arguments to ErrorS should always be Key Value pairs. Please check if there is any key or value missing.` + logger.Info("hello", "key") // want `Additional arguments to Info should always be Key Value pairs. Please check if there is any key or value missing.` + logger.Error(nil, "hello", "key") // want `Additional arguments to Error should always be Key Value pairs. Please check if there is any key or value missing.` + logger2.Info("hello", "key") // want `Additional arguments to Info should always be Key Value pairs. Please check if there is any key or value missing.` + logger2.Error(nil, "hello", "key") // want `Additional arguments to Error should always be Key Value pairs. Please check if there is any key or value missing.` // non-string keys klog.InfoS("hello", "1", 2) klog.InfoS("hello", 1, 2) // want `Key positional arguments are expected to be inlined constant strings. Please replace 1 provided with string value` klog.ErrorS(nil, "hello", "1", 2) klog.ErrorS(nil, "hello", 1, 2) // want `Key positional arguments are expected to be inlined constant strings. Please replace 1 provided with string value` + logger.Info("hello", "1", 2) + logger.Info("hello", 1, 2) // want `Key positional arguments are expected to be inlined constant strings. Please replace 1 provided with string value` + logger.Error(nil, "hello", "1", 2) + logger.Error(nil, "hello", 1, 2) // want `Key positional arguments are expected to be inlined constant strings. Please replace 1 provided with string value` + logger2.Info("hello", "1", 2) + logger2.Info("hello", 1, 2) // want `Key positional arguments are expected to be inlined constant strings. Please replace 1 provided with string value` + logger2.Error(nil, "hello", "1", 2) + logger2.Error(nil, "hello", 1, 2) // want `Key positional arguments are expected to be inlined constant strings. Please replace 1 provided with string value` // variadic input to klog.Info*, klog.Error*, klog.LoggerWithValues functions kvs := []interface{}{"key1", "value1"} @@ -61,7 +77,15 @@ func parameterCalls() { klog.Info(kvs...) klog.Error(kvs...) - logger := klog.FromContext(context.Background()) + logger.Info("foo message", kvs) // want `Additional arguments to Info should always be Key Value pairs. Please check if there is any key or value missing.` + logger.Error(nil, "foo error message", kvs...) + logger.Info("message", kvs...) + logger.Error(nil, "foo error message", kvs...) + logger2.Info("foo message", kvs) // want `Additional arguments to Info should always be Key Value pairs. Please check if there is any key or value missing.` + logger2.Error(nil, "foo error message", kvs...) + logger2.Info("message", kvs...) + logger2.Error(nil, "foo error message", kvs...) + klog.LoggerWithValues(logger, kvs...) klog.LoggerWithValues(logger, kvs) // want `Additional arguments to LoggerWithValues should always be Key Value pairs. Please check if there is any key or value missing.` }