Merge pull request #1460 from crazy-max/golangci-lint-v2

update golangci-lint to v2.1.6
This commit is contained in:
CrazyMax
2025-08-03 20:25:06 +02:00
committed by GitHub
14 changed files with 170 additions and 117 deletions

View File

@@ -1,12 +1,11 @@
version: "2"
run:
timeout: 30m
modules-download-mode: vendor
build-tags:
- containers_image_openpgp
- exclude_graphdriver_btrfs
- exclude_graphdriver_devicemapper
# default uses Go version from the go.mod file, fallback on the env var
# `GOVERSION`, fallback on 1.17: https://golangci-lint.run/usage/configuration/#run-configuration
go: "1.23"
linters:
enable:
@@ -14,10 +13,7 @@ linters:
- depguard
- forbidigo
- gocritic
- gofmt
- goimports
- gosec
- gosimple
- govet
- ineffassign
- makezero
@@ -27,19 +23,15 @@ linters:
- revive
- staticcheck
- testifylint
- typecheck
- unused
- whitespace
disable-all: true
linters-settings:
settings:
gocritic:
disabled-checks:
- "ifElseChain"
- "assignOp"
- "appendAssign"
- "singleCaseSwitch"
- "exitAfterDefer" # FIXME
importas:
alias:
- pkg: "github.com/opencontainers/image-spec/specs-go/v1"
@@ -54,52 +46,79 @@ linters-settings:
rules:
main:
deny:
- pkg: "github.com/containerd/containerd/errdefs"
desc: The containerd errdefs package was migrated to a separate module. Use github.com/containerd/errdefs instead.
- pkg: "github.com/containerd/containerd/log"
desc: The containerd log package was migrated to a separate module. Use github.com/containerd/log instead.
- pkg: "github.com/containerd/containerd/platforms"
desc: The containerd platforms package was migrated to a separate module. Use github.com/containerd/platforms instead.
- pkg: "io/ioutil"
desc: The io/ioutil package has been deprecated.
forbidigo:
forbid:
- '^fmt\.Errorf(# use errors\.Errorf instead)?$'
- '^platforms\.DefaultString(# use platforms\.Format(platforms\.DefaultSpec()) instead\.)?$'
- pattern: ^context\.WithCancel(# use context\.WithCancelCause instead)?$
- pattern: ^context\.WithDeadline(# use context\.WithDeadline instead)?$
- pattern: ^context\.WithTimeout(# use context\.WithTimeoutCause instead)?$
- pattern: ^ctx\.Err(# use context\.Cause instead)?$
- pattern: ^fmt\.Errorf(# use errors\.Errorf instead)?$
- pattern: ^platforms\.DefaultString(# use platforms\.Format(platforms\.DefaultSpec()) instead\.)?$
gosec:
excludes:
- G204 # Audit use of command execution
- G402 # TLS MinVersion too low
- G115 # integer overflow conversion
- G204
- G402
- G115
config:
G306: "0644"
testifylint:
disable:
# disable rules that reduce the test condition
- "empty"
- "bool-compare"
- "len"
- "negative-positive"
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
-
linters:
- revive
text: stutters
-
linters:
- revive
text: empty-block
-
linters:
- revive
text: superfluous-else
-
linters:
- revive
text: unused-parameter
-
linters:
- revive
text: redefines-builtin-id
-
linters:
- revive
text: if-return
paths:
- .*\.pb\.go$
formatters:
enable:
- gofmt
- goimports
exclusions:
generated: lax
paths:
- .*\.pb\.go$
issues:
exclude-files:
- ".*\\.pb\\.go$"
exclude-rules:
- linters:
- revive
text: "stutters"
- linters:
- revive
text: "empty-block"
- linters:
- revive
text: "superfluous-else"
- linters:
- revive
text: "unused-parameter"
- linters:
- revive
text: "redefines-builtin-id"
- linters:
- revive
text: "if-return"
# show all
max-issues-per-linter: 0
max-same-issues: 0

View File

@@ -79,7 +79,7 @@ func (s *ServeCmd) Run(ctx *Context) error {
case "block":
defer profile.Start(profile.BlockProfile, profilePath).Stop()
default:
log.Fatal().Msgf("Unknown profiler: %s", s.Profiler)
log.Fatal().Msgf("Unknown profiler: %s", s.Profiler) //nolint:gocritic // defer not set if profiler is unknown
}
}

View File

@@ -16,6 +16,10 @@ variable "GOLANGCI_LINT_MULTIPLATFORM" {
default = null
}
variable "GOLANGCI_FROM_SOURCE" {
default = null
}
target "_common" {
args = {
GO_VERSION = GO_VERSION
@@ -134,6 +138,9 @@ target "lint" {
inherits = ["_common"]
dockerfile = "./hack/lint.Dockerfile"
target = "lint"
args = {
GOLANGCI_FROM_SOURCE = GOLANGCI_FROM_SOURCE
}
output = ["type=cacheonly"]
platforms = GOLANGCI_LINT_MULTIPLATFORM != null ? [
"darwin/amd64",

View File

@@ -3,20 +3,34 @@
ARG GO_VERSION="1.23"
ARG XX_VERSION="1.6.1"
ARG ALPINE_VERSION="3.21"
ARG GOLANGCI_LINT_VERSION="v1.62"
ARG GOLANGCI_LINT_VERSION="v2.1.6"
ARG GOLANGCI_FROM_SOURCE="true"
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base
ENV GOFLAGS="-buildvcs=false"
RUN apk add --no-cache gcc linux-headers musl-dev
COPY --from=xx --link / /
WORKDIR /src
FROM base AS golangci-build
ARG GOLANGCI_LINT_VERSION
ADD "https://github.com/golangci/golangci-lint.git#${GOLANGCI_LINT_VERSION}" .
RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/ go mod download
RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/ mkdir -p out && go build -o /out/golangci-lint ./cmd/golangci-lint
FROM --platform=$BUILDPLATFORM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
FROM scratch AS golangci-binary-false
COPY --from=golangci-lint /usr/bin/golangci-lint golangci-lint
FROM scratch AS golangci-binary-true
COPY --from=golangci-build /out/golangci-lint golangci-lint
FROM golangci-binary-${GOLANGCI_FROM_SOURCE} AS golangci-binary
FROM base AS lint
ARG TARGETPLATFORM
RUN --mount=type=bind,target=. \
--mount=type=cache,target=/root/.cache,id=lint-cache-$TARGETPLATFORM \
--mount=from=golangci-lint,source=/usr/bin/golangci-lint,target=/usr/bin/golangci-lint \
--mount=from=golangci-binary,source=/golangci-lint,target=/usr/bin/golangci-lint \
xx-go --wrap && \
golangci-lint run ./...

View File

@@ -87,11 +87,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
q := u.Query()
u.RawQuery = q.Encode()
hc := http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
defer cancel()
cancelCtx, cancel := context.WithCancelCause(context.Background())
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, *c.cfg.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
req, err := http.NewRequestWithContext(ctx, "POST", u.String(), dataBuf)
hc := http.Client{}
req, err := http.NewRequestWithContext(timeoutCtx, "POST", u.String(), dataBuf)
if err != nil {
return err
}

View File

@@ -128,11 +128,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
hc := http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
defer cancel()
cancelCtx, cancel := context.WithCancelCause(context.Background())
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, *c.cfg.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
req, err := http.NewRequestWithContext(ctx, "POST", u.String(), dataBuf)
hc := http.Client{}
req, err := http.NewRequestWithContext(timeoutCtx, "POST", u.String(), dataBuf)
if err != nil {
return err
}

View File

@@ -89,11 +89,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
q.Set("token", token)
u.RawQuery = q.Encode()
hc := http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
defer cancel()
cancelCtx, cancel := context.WithCancelCause(context.Background())
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, *c.cfg.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
req, err := http.NewRequestWithContext(ctx, "POST", u.String(), bytes.NewBuffer(jsonBody))
hc := http.Client{}
req, err := http.NewRequestWithContext(timeoutCtx, "POST", u.String(), bytes.NewBuffer(jsonBody))
if err != nil {
return err
}

View File

@@ -81,11 +81,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
q := u.Query()
u.RawQuery = q.Encode()
hc := http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
defer cancel()
cancelCtx, cancel := context.WithCancelCause(context.Background())
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, *c.cfg.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
req, err := http.NewRequestWithContext(ctx, "POST", u.String(), dataBuf)
hc := http.Client{}
req, err := http.NewRequestWithContext(timeoutCtx, "POST", u.String(), dataBuf)
if err != nil {
return err
}

View File

@@ -122,11 +122,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
}
u.Path = path.Join(u.Path, "api/v1/chat.postMessage")
hc := http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
defer cancel()
cancelCtx, cancel := context.WithCancelCause(context.Background())
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, *c.cfg.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
req, err := http.NewRequestWithContext(ctx, "POST", u.String(), dataBuf)
hc := http.Client{}
req, err := http.NewRequestWithContext(timeoutCtx, "POST", u.String(), dataBuf)
if err != nil {
return err
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/crazy-max/diun/v4/internal/model"
"github.com/crazy-max/diun/v4/internal/msg"
"github.com/crazy-max/diun/v4/internal/notif/notifier"
"github.com/pkg/errors"
)
// Client represents an active signalrest notification object
@@ -62,11 +63,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
hc := http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
defer cancel()
cancelCtx, cancel := context.WithCancelCause(context.Background())
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, *c.cfg.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
req, err := http.NewRequestWithContext(ctx, "POST", c.cfg.Endpoint, bytes.NewBuffer(body))
hc := http.Client{}
req, err := http.NewRequestWithContext(timeoutCtx, "POST", c.cfg.Endpoint, bytes.NewBuffer(body))
if err != nil {
return err
}

View File

@@ -110,11 +110,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
hc := http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(10)*time.Second)
defer cancel()
cancelCtx, cancel := context.WithCancelCause(context.Background())
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, 10*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
req, err := http.NewRequestWithContext(ctx, "POST", webhookURL, bytes.NewBuffer(jsonBody))
hc := http.Client{}
req, err := http.NewRequestWithContext(timeoutCtx, "POST", webhookURL, bytes.NewBuffer(jsonBody))
if err != nil {
return err
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/crazy-max/diun/v4/internal/model"
"github.com/crazy-max/diun/v4/internal/msg"
"github.com/crazy-max/diun/v4/internal/notif/notifier"
"github.com/pkg/errors"
)
// Client represents an active webhook notification object
@@ -47,11 +48,12 @@ func (c *Client) Send(entry model.NotifEntry) error {
return err
}
hc := http.Client{}
ctx, cancel := context.WithTimeout(context.Background(), *c.cfg.Timeout)
defer cancel()
cancelCtx, cancel := context.WithCancelCause(context.Background())
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, *c.cfg.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
req, err := http.NewRequestWithContext(ctx, "POST", c.cfg.Endpoint, bytes.NewBuffer(body))
hc := http.Client{}
req, err := http.NewRequestWithContext(timeoutCtx, "POST", c.cfg.Endpoint, bytes.NewBuffer(body))
if err != nil {
return err
}

View File

@@ -68,7 +68,7 @@ func newInClusterClient(opts Options) (*kubernetes.Clientset, error) {
config.Host = opts.Endpoint
}
if opts.TLSInsecure != nil {
config.TLSClientConfig.Insecure = *opts.TLSInsecure
config.Insecure = *opts.TLSInsecure
}
return kubernetes.NewForConfig(config)
@@ -80,7 +80,7 @@ func newExternalClusterClientFromFile(opts Options, file string) (*kubernetes.Cl
return nil, err
}
if opts.TLSInsecure != nil {
configFromFlags.TLSClientConfig.Insecure = *opts.TLSInsecure
configFromFlags.Insecure = *opts.TLSInsecure
}
return kubernetes.NewForConfig(configFromFlags)
@@ -113,7 +113,7 @@ func newExternalClusterClient(opts Options) (*kubernetes.Clientset, error) {
}
}
if opts.TLSInsecure != nil {
config.TLSClientConfig.Insecure = *opts.TLSInsecure
config.Insecure = *opts.TLSInsecure
}
return kubernetes.NewForConfig(config)

View File

@@ -5,6 +5,7 @@ import (
"time"
"github.com/containers/image/v5/types"
"github.com/pkg/errors"
)
// Client represents an active docker registry object
@@ -43,9 +44,11 @@ func New(opts Options) (*Client, error) {
func (c *Client) timeoutContext() (context.Context, context.CancelFunc) {
ctx := context.Background()
var cancel context.CancelFunc = func() {}
var cancelFunc context.CancelFunc = func() {}
if c.opts.Timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, c.opts.Timeout)
cancelCtx, cancel := context.WithCancelCause(ctx)
ctx, _ = context.WithTimeoutCause(cancelCtx, c.opts.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
cancelFunc = func() { cancel(errors.WithStack(context.Canceled)) }
}
return ctx, cancel
return ctx, cancelFunc
}