Skip to content

Gate gofmt and go vet on the Go test tooling - #166

Open
stevebeattie wants to merge 1 commit into
chainguard-dev:mainfrom
stevebeattie:add-go-lint-gate
Open

Gate gofmt and go vet on the Go test tooling#166
stevebeattie wants to merge 1 commit into
chainguard-dev:mainfrom
stevebeattie:add-go-lint-gate

Conversation

@stevebeattie

Copy link
Copy Markdown
Member

Why

Neither gofmt nor go vet was checked anywhere. CI runs go test only, which
applies no formatting check and enables just a subset of vet — so an unformatted
file reached main unnoticed (the stanza comment added in #162, fixed in passing
in #163). A gate that would have caught it costs one step.

There is no .pre-commit-config.yaml in the repo and no golangci config either,
so this is CI-only. Pre-commit could be added on top later; CI is the
authoritative gate and doesn't depend on per-clone setup.

Change

make lint-go checks gofmt and runs go vet in full across
tests/oscap-offline, and the offline workflow runs it. Documented in the
README's testing section alongside the other gates.

One detail worth keeping

gofmt -l is checked by its output, not its exit status:

unformatted=$$(gofmt -l .); \
if [ -n "$$unformatted" ]; then ... exit 1; fi

gofmt -l exits 0 whether or not it lists anything, so the natural
gofmt -l . && ... succeeds on unformatted input. That is precisely the trap
that made the original violation invisible — and it also cost me a wrong
conclusion while diagnosing it, before I re-checked. Hence the comment in the
recipe.

Verification

Exercised against both failure modes with deliberately broken files, then
removed:

Probe Result
unformatted file fails, naming the file
formatted file with a vet problem (Printf verb mismatch) fails, naming the diagnostic
clean tree (main as it stands) passes — gofmt: clean, go vet: clean

actionlint issue count unchanged from main; zizmor no findings.

Noted separately, not changed here

make validate_mirrors and make test-offline both run go test without -v,
so their CI logs show ok but not what was covered — #164's run, for instance,
passes the mirror test without the log showing that it compared 8 files. Adding
-v (or an explicit count assertion) would make that signal auditable. Happy to
do it, but it is a different concern from linting.

🤖 Generated with Claude Code

Neither was checked anywhere. CI ran `go test` only, which applies no
formatting check and enables just a subset of vet, so an unformatted file
reached main unnoticed — the stanza comment added in chainguard-dev#162, fixed in passing
in chainguard-dev#163. A gate that would have caught it costs one step.

`make lint-go` checks gofmt and runs vet in full over tests/oscap-offline,
and the offline workflow runs it. Verified against both failure modes with
deliberately broken files: unformatted code fails naming the file, and a
formatted file with a vet problem (a Printf verb mismatch, which is in the
subset `go test` already covers, chosen so the two layers are visibly
distinct) fails too. Clean on main as it stands.

gofmt -l is checked by its output rather than its exit status, and that is
worth stating in the recipe because it is the trap that hides this class of
problem: `gofmt -l` exits 0 whether or not it lists anything, so the natural
`gofmt -l . && ...` succeeds on unformatted input. Getting this wrong is what
made the original violation invisible, and it also cost me a wrong conclusion
while diagnosing it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant