Skip to content

[9.3] .golangci.yml: enable the modernize linter#51961

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

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

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)"

@orestisfl orestisfl self-assigned this Jul 15, 2026
@orestisfl orestisfl requested review from a team as code owners July 15, 2026 08:15
@orestisfl orestisfl requested review from AndersonQ and leehinman and removed request for a team July 15, 2026 08:15
@orestisfl orestisfl added Team:Elastic-Agent-Data-Plane Label for the Agent Data Plane team skip-changelog labels Jul 15, 2026
@orestisfl orestisfl requested review from samuelvl and swiatekm and removed request for a team July 15, 2026 08:15
@botelastic botelastic Bot added needs_team Indicates that the issue/PR needs a Team:* label and removed needs_team Indicates that the issue/PR needs a Team:* label labels 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.

@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?

@mergify

mergify Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

This pull request is now in conflicts. Could you fix it? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

git fetch upstream
git checkout -b modernize-9.3 upstream/modernize-9.3
git merge upstream/9.3
git push upstream modernize-9.3

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 (except for
some manual changes that were highlighted in the review) 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.
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