Switch golangci-lint plugins to compiled-in modules

Co-authored-by: Davanum Srinivas <davanum@gmail.com>
This commit is contained in:
Jordan LiggittandDavanum Srinivas committed 2026-09-03 23:23:53 -04:00
1 parent fde4ae2ef6
commit 728c52bc00
9 files changed
+100 -69

No files matched your search

+6 -5
View File
@@ -316,8 +316,8 @@ linters:
settings: # please keep this alphabetized
custom:
logcheck:
# Installed there by hack/verify-golangci-lint.sh.
path: _output/local/bin/logcheck.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: structured logging checker
original-url: k8s.io/logtools/logcheck
settings:
@@ -391,8 +391,8 @@ linters:
# API design needed).
-contextual k8s.io/client-go/plugin/pkg/client/auth/.*
sorted:
# Installed there by hack/verify-golangci-lint.sh.
path: _output/local/bin/sorted.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: check if feature gates are sorted
original-url: k8s.io/kubernetes/hack/tools/golangci-lint/sorted
settings:
@@ -406,7 +406,8 @@ linters:
- test/e2e/feature/feature.go
- test/e2e/environment/environment.go
kubeapilinter:
path: _output/local/bin/kube-api-linter.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: kube-api-linter and lints Kube like APIs based on API conventions and best practices.
original-url: sigs.k8s.io/kube-api-linter
settings:
+6 -5
View File
@@ -329,8 +329,8 @@ linters:
settings: # please keep this alphabetized
custom:
logcheck:
# Installed there by hack/verify-golangci-lint.sh.
path: _output/local/bin/logcheck.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: structured logging checker
original-url: k8s.io/logtools/logcheck
settings:
@@ -404,8 +404,8 @@ linters:
# API design needed).
-contextual k8s.io/client-go/plugin/pkg/client/auth/.*
sorted:
# Installed there by hack/verify-golangci-lint.sh.
path: _output/local/bin/sorted.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: check if feature gates are sorted
original-url: k8s.io/kubernetes/hack/tools/golangci-lint/sorted
settings:
@@ -419,7 +419,8 @@ linters:
- test/e2e/feature/feature.go
- test/e2e/environment/environment.go
kubeapilinter:
path: _output/local/bin/kube-api-linter.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: kube-api-linter and lints Kube like APIs based on API conventions and best practices.
original-url: sigs.k8s.io/kube-api-linter
settings:
+6 -5
View File
@@ -186,22 +186,23 @@ linters:
settings: # please keep this alphabetized
custom:
logcheck:
# Installed there by hack/verify-golangci-lint.sh.
path: _output/local/bin/logcheck.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: structured logging checker
original-url: k8s.io/logtools/logcheck
settings:
config: |
{{include "hack/logcheck.conf" | indent 12 | trim}}
sorted:
# Installed there by hack/verify-golangci-lint.sh.
path: _output/local/bin/sorted.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: check if feature gates are sorted
original-url: k8s.io/kubernetes/hack/tools/golangci-lint/sorted
settings:
{{include "hack/tools/golangci-lint/sorted/config.yaml" | indent 10 | trim}}
kubeapilinter:
path: _output/local/bin/kube-api-linter.so
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: kube-api-linter and lints Kube like APIs based on API conventions and best practices.
original-url: sigs.k8s.io/kube-api-linter
settings:
+4 -10
View File
@@ -2,15 +2,13 @@ module k8s.io/kubernetes/hack/tools/golangci-lint
go 1.26.0
tool (
github.com/golangci/golangci-lint/v2/cmd/golangci-lint
sigs.k8s.io/kube-api-linter/pkg/plugin
sigs.k8s.io/logtools/logcheck
)
require (
github.com/golangci/golangci-lint/v2 v2.11.2
github.com/golangci/plugin-module-register v0.1.2
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
golang.org/x/tools v0.42.0
sigs.k8s.io/kube-api-linter v0.0.0-20260716143926-092fe0c72997
sigs.k8s.io/logtools v0.10.1
)
require (
@@ -93,10 +91,8 @@ require (
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
github.com/golangci/go-printf-func-name v0.1.1 // indirect
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
github.com/golangci/golangci-lint/v2 v2.11.2 // indirect
github.com/golangci/golines v0.15.0 // indirect
github.com/golangci/misspell v0.8.0 // indirect
github.com/golangci/plugin-module-register v0.1.2 // indirect
github.com/golangci/revgrep v0.8.0 // indirect
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
@@ -219,7 +215,5 @@ require (
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
mvdan.cc/gofumpt v0.9.2 // indirect
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect
sigs.k8s.io/kube-api-linter v0.0.0-20260716143926-092fe0c72997 // indirect
sigs.k8s.io/logtools v0.10.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
+51
View File
@@ -0,0 +1,51 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"os"
"runtime"
"runtime/debug"
"github.com/golangci/golangci-lint/v2/pkg/commands"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
// These imports register the custom linters.
_ "sigs.k8s.io/kube-api-linter"
_ "sigs.k8s.io/logtools/logcheck/gclplugin"
_ "k8s.io/kubernetes/hack/tools/golangci-lint/sorted/plugin"
)
func main() {
// populate the golangci-lint version so the verify config command works
golangCIVersion := ""
if info, ok := debug.ReadBuildInfo(); ok {
for _, dep := range info.Deps {
if dep.Path == "github.com/golangci/golangci-lint/v2" {
golangCIVersion = dep.Version
break
}
}
}
if err := commands.Execute(commands.BuildInfo{GoVersion: runtime.Version(), Version: golangCIVersion}); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "The command is terminated due to an error: %v\n", err)
os.Exit(exitcodes.Failure)
}
}
+1 -1
View File
@@ -221,7 +221,7 @@ codebase. Run it locally before submitting pull requests that modify feature gat
## Troubleshooting
1. **Enable debug mode**: Set `debug: true` in your configuration to see processing details
2. **Check plugin build**: Ensure the plugin is correctly built with `go build -buildmode=plugin`
2. **Check the build**: Ensure `hack/tools/golangci-lint/main.go` imports the `plugin` package
3. **Verify file paths**: Confirm target files are in the default list or explicitly configured
4. **Test with standalone tool**: Run `go run main.go path/to/file.go` to test specific files
@@ -2,7 +2,7 @@ linters:
settings:
custom:
sorted:
path: /path/to/sorted.so
type: module
description: Checks if feature gates are sorted alphabetically
original-url: k8s.io/kubernetes/hack/tools/golangci-lint/sorted
settings:
@@ -14,27 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// This must be package main
package main
// Package plugin registers the sorted linter as a golangci-lint module plugin.
package plugin
import (
"bytes"
"encoding/json"
"fmt"
"github.com/golangci/plugin-module-register/register"
"golang.org/x/tools/go/analysis"
"k8s.io/kubernetes/hack/tools/golangci-lint/sorted/pkg"
)
type analyzerPlugin struct{}
func (*analyzerPlugin) GetAnalyzers() []*analysis.Analyzer {
return []*analysis.Analyzer{pkg.NewAnalyzer()}
}
// AnalyzerPlugin is the entry point for golangci-lint.
var AnalyzerPlugin analyzerPlugin
// settings defines the configuration options for the sorted linter
type settings struct {
// Debug enables debug logging
@@ -54,8 +47,7 @@ var defaultTargetFiles = []string{
"test/e2e/environment/environment.go",
}
// New is the entry point for golangci-lint plugin system
func New(pluginSettings interface{}) ([]*analysis.Analyzer, error) {
func New(pluginSettings interface{}) (register.LinterPlugin, error) {
// Create default config
config := pkg.Config{}
@@ -86,11 +78,24 @@ func New(pluginSettings interface{}) ([]*analysis.Analyzer, error) {
fmt.Printf("sorted settings: %+v\n", s)
fmt.Printf("final config: %+v\n", config)
}
} else {
config.Files = defaultTargetFiles
}
// Get the analyzer with config
analyzer := pkg.NewAnalyzerWithConfig(config)
return linterPlugin{config: config}, nil
}
// Return the analyzer
return []*analysis.Analyzer{analyzer}, nil
type linterPlugin struct {
config pkg.Config
}
func (l linterPlugin) BuildAnalyzers() ([]*analysis.Analyzer, error) {
return []*analysis.Analyzer{pkg.NewAnalyzerWithConfig(l.config)}, nil
}
func (l linterPlugin) GetLoadMode() string {
return register.LoadModeSyntax
}
func init() {
register.Plugin("sorted", New)
}
+3 -25
View File
@@ -123,22 +123,11 @@ kube::util::ensure-temp-dir
# Install golangci-lint.
#
# hack/tools/golangci-lint uses the "tool" directive in a stand-alone
# go.mod.
#
# Installing from source (https://golangci-lint.run/welcome/install/#install-from-sources)
# Building from source (https://golangci-lint.run/welcome/install/#install-from-sources)
# is not recommended, but for Kubernetes we prefer it because it avoids the need for
# pre-built binaries for different platforms and gives more insights on dependencies.
# pre-built binaries for different platforms, gives more insights on dependencies, and allows custom plugins.
echo "installing golangci-lint, logcheck kube-api-linter and sorted plugins from hack/tools/golangci-lint into ${GOBIN}"
GOTOOLCHAIN="$(kube::golang::hack_tools_gotoolchain)" go -C "${KUBE_ROOT}/hack/tools/golangci-lint" install github.com/golangci/golangci-lint/v2/cmd/golangci-lint
if [ "${golangci_config}" ]; then
# Plugins cannot be used without a config.
# This uses `go build` because `go install -buildmode=plugin` doesn't work
# (on purpose: https://github.com/golang/go/issues/64964).
GOTOOLCHAIN="$(kube::golang::hack_tools_gotoolchain)" go -C "${KUBE_ROOT}/hack/tools/golangci-lint" build -o "${GOBIN}/logcheck.so" -buildmode=plugin sigs.k8s.io/logtools/logcheck/plugin
GOTOOLCHAIN="$(kube::golang::hack_tools_gotoolchain)" go -C "${KUBE_ROOT}/hack/tools/golangci-lint" build -o "${GOBIN}/kube-api-linter.so" -buildmode=plugin sigs.k8s.io/kube-api-linter/pkg/plugin
GOTOOLCHAIN="$(kube::golang::hack_tools_gotoolchain)" go -C "${KUBE_ROOT}/hack/tools/golangci-lint" build -o "${GOBIN}/sorted.so" -buildmode=plugin k8s.io/kubernetes/hack/tools/golangci-lint/sorted/plugin
fi
GOTOOLCHAIN="$(kube::golang::hack_tools_gotoolchain)" go -C "${KUBE_ROOT}/hack/tools/golangci-lint" build -o "${GOBIN}/golangci-lint" .
# Verify that the given config is valid (if one is provided). "golangci-lint run" does not
# do that, which makes it easy to miss mistakes while editing the configuration.
@@ -159,17 +148,6 @@ EOF
fi
if [ "${golangci_config}" ]; then
# The relative path to _output/local/bin only works if that actually is the
# GOBIN. If not, then we have to make a temporary copy of the config and
# replace the path with an absolute one. This could be done also
# unconditionally, but the invocation that is printed below is nicer if we
# don't to do it when not required.
if grep -q 'path: _output/local/bin/' "${golangci_config}" &&
[ "${GOBIN}" != "${KUBE_ROOT}/_output/local/bin" ]; then
patched_golangci_config="${KUBE_TEMP}/$(basename "${golangci_config}")"
sed -e "s;path: _output/local/bin/;path: ${GOBIN}/;" "${golangci_config}" >"${patched_golangci_config}"
golangci_config="${patched_golangci_config}"
fi
golangci+=(--config="${golangci_config}")
fi