Skip to content

[9.5] .golangci.yml: enable the modernize linter#51959

Open
orestisfl wants to merge 4 commits into
elastic:9.5from
orestisfl:modernize-9.5
Open

[9.5] .golangci.yml: enable the modernize linter#51959
orestisfl wants to merge 4 commits into
elastic:9.5from
orestisfl:modernize-9.5

Conversation

@orestisfl

Copy link
Copy Markdown
Contributor

Manual backport of #51840 using the shell script:

#!/usr/bin/env bash
# Reproduces the Go changes of PR1 deterministically.
# Precondition: only .golangci.yml is modified (by hand); the tree is otherwise
# a clean checkout. Run from the repository root.
set -euo pipefail

OWNER="@elastic/elastic-agent-data-plane"
export CGO_ENABLED=1
MAX_PASSES=10

modernize() {
	golangci-lint run --enable-only modernize \
		--max-issues-per-linter 0 --max-same-issues 0 --timeout=90m --fix ./...
}

# Fixpoint: fmt, then modernize, then apply //go:fix inline directives. Each
# step can unlock the next, so iterate until a full pass changes nothing.
for pass in $(seq "$MAX_PASSES"); do
	echo ">>> pass $pass: fmt"
	before="$(git diff | git hash-object --stdin)"
	golangci-lint fmt ./...
	echo ">>> pass $pass: modernize --fix"
	if modernize; then :; fi
	echo ">>> pass $pass: go fix -inline"
	# go fix may exit non-zero when an inline leaves an import unused; the next
	# pass's `golangci-lint fmt` drops those imports, so ignore its status.
	if go fix -inline ./...; then :; fi
	echo ">>> pass $pass done: $(git diff --name-only | wc -l) files changed"
	[ "$before" = "$(git diff | git hash-object --stdin)" ] && { echo ">>> fixpoint at pass $pass"; break; }
done
golangci-lint fmt ./...

# Keep only the .go files owned by $OWNER; revert everyone else's files.
changed="$(mktemp)"
keep="$(mktemp)"
trap 'rm -f "$changed" "$keep"' EXIT
git diff --name-only -- '*.go' | sort -u >"$changed"
git diff --name-only -- '*.go' | xargs -r codeowners -o "$OWNER" \
	| awk '{print $1}' | sort -u >"$keep"
comm -23 "$changed" "$keep" | tr '\n' '\0' | xargs -0 -r git checkout --

echo "PR1 data-plane .go files: $(git diff --name-only -- '*.go' | wc -l)"

Enable the modernize linter from golangci-lint's suite. It flags
outdated Go syntax and rewrites it to modern equivalents: min/max
builtins, range-over-int loops, slices/maps helpers, any, t.Context()
in tests, fmt.Appendf, strings.CutPrefix, and more. Keeping it enabled
stops outdated patterns from re-entering the codebase, which matters
more now that much code is produced by AI agents trained on older Go,
and it often yields simpler, more efficient code.

The omitzero analyzer is disabled: it rewrites ,omitempty struct tags to
,omitzero, which changes JSON marshaling semantics and is not a
mechanical, behavior-preserving fix.

The loop also runs `go fix -inline`, which applies //go:fix inline
directives. modernize marks its own pointer helpers with the directive,
and dependencies/stdlib carry it on deprecated APIs, so this pulls in
mechanical migrations such as io/ioutil -> io and reflect.Ptr ->
reflect.Pointer. `go fix` inlines the call sites but never deletes the
now-dead helper declarations; a follow-up commit removes those.

Every Go change here is a linter/`go fix` auto-fix, restricted to the
files owned by @elastic/elastic-agent-data-plane; the rest of the
repository is modernized in a stacked follow-up PR so each team reviews
only its own code.

The .golangci.yml change is made by hand. The Go changes are then fully
reproducible by running this with bash from the repository root:

set -euo pipefail

OWNER="@elastic/elastic-agent-data-plane"
export CGO_ENABLED=1
MAX_PASSES=10

modernize() {
        golangci-lint run --enable-only modernize \
                --max-issues-per-linter 0 --max-same-issues 0 --timeout=90m --fix ./...
}

for pass in $(seq "$MAX_PASSES"); do
        echo ">>> pass $pass: fmt"
        before="$(git diff | git hash-object --stdin)"
        golangci-lint fmt ./...
        echo ">>> pass $pass: modernize --fix"
        if modernize; then :; fi
        echo ">>> pass $pass: go fix -inline"
        if go fix -inline ./...; then :; fi
        echo ">>> pass $pass done: $(git diff --name-only | wc -l) files changed"
        [ "$before" = "$(git diff | git hash-object --stdin)" ] && { echo ">>> fixpoint at pass $pass"; break; }
done
golangci-lint fmt ./...

changed="$(mktemp)"
keep="$(mktemp)"
trap 'rm -f "$changed" "$keep"' EXIT
git diff --name-only -- '*.go' | sort -u >"$changed"
git diff --name-only -- '*.go' | xargs -r codeowners -o "$OWNER" \
        | awk '{print $1}' | sort -u >"$keep"
comm -23 "$changed" "$keep" | tr '\n' '\0' | xargs -0 -r git checkout --

echo "PR1 data-plane .go files: $(git diff --name-only -- '*.go' | wc -l)"
modernize marks trivial pointer helpers (func f(v T) *T { return &v })
with //go:fix inline and rewrites the body to new(v). `go fix -inline`
then replaces every call site with new(...) but does not delete the
helper declaration, leaving it unused.

Remove those now-dead helpers so the unused linter stays clean. This is
the manual step `go fix` cannot do; all removed functions have zero
remaining callers.
@orestisfl orestisfl self-assigned this Jul 15, 2026
@orestisfl orestisfl requested review from a team as code owners July 15, 2026 08:08
@orestisfl orestisfl requested review from AndersonQ, blakerouse, khushijain21 and lorienhu and removed request for a team July 15, 2026 08:08
@botelastic botelastic Bot added the needs_team Indicates that the issue/PR needs a Team:* label label Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🤖 GitHub comments

Just comment with:

  • run docs-build : Re-trigger the docs validation. (use unformatted text in the comment!)
  • /test : Run the Buildkite pipeline.

@orestisfl orestisfl added backport cleanup Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team skip-changelog and removed needs_team Indicates that the issue/PR needs a Team:* label labels Jul 15, 2026
@AndersonQ

Copy link
Copy Markdown
Member

@orestisfl, this PR does not change .golangci.yml as the original did: https://github.com/elastic/beats/pull/51840/changes#diff-6179837f7df53a6f05c522b6b7bb566d484d5465d9894fb04910dd08bb40dcc9

Was it intentional?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants