From b93d09d02715ddabb3bf5f0a2b01538a982765eb Mon Sep 17 00:00:00 2001 From: sneak Date: Tue, 3 Nov 2026 20:58:36 +0000 Subject: [PATCH] Update the canonical .golangci.yml for golangci-lint v2.15.0 (closes #142) Moves the pin to v2.15.0 and enables canonicalheader again, because that release fixes the random misses behind https://git.eeqj.de/sneak/prompts/issues/105. The depguard exemption reached every directory below one ending in test, and a whole checkout under such a directory. It now covers only the files directly inside, and the directory a repository is cloned into does not count. gomodguard_v2 also blocks github.com/go-redis/redis/v9, whose pre-releases can still be imported. uniq-by-line is now false, so a line that trips two linters reports both findings. Three comments are corrected. A new comment says the file has no formatters section, so golangci-lint run does not run gofmt. Model: opus-5-5 --- .golangci.yml | 34 ++++++++++++++++++++++------------ TODO.md | 21 +++++++++++++++++++++ prompts/REPO_POLICIES.md | 6 +++--- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 1d6b3c6..251f85c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,6 +3,9 @@ version: "2" # Config schema uses the golangci-lint v2 layout (settings live under # linters.settings, not top-level linters-settings) so that the # thresholds below are actually applied by golangci-lint >= v2. +# +# This file has no formatters section, so golangci-lint run does not run +# gofmt. A repository's script/fmt-check runs it, on the host. run: timeout: 5m @@ -16,17 +19,15 @@ linters: - gomodguard_v2 disable: # Genuinely incompatible with project patterns - - exhaustruct # Requires all struct fields - - exhaustruct_v5 # Requires all struct fields (successor to exhaustruct) + - exhaustruct_v5 # Requires all struct fields - godot # Requires comments to end with periods - wrapcheck # Too verbose for internal packages - varnamelen # Short names like db, id are idiomatic Go # Deprecated: the warning is attached to the old name, so it is # silenced by disabling that name, not by enabling the successor. + - exhaustruct # Deprecated, replaced by exhaustruct_v5 - wsl # Deprecated, replaced by wsl_v5 - gomodguard # Deprecated, replaced by gomodguard_v2 - # Misses findings at random in v2.14.0; back once a pinned release fixes it - - canonicalheader settings: lll: line-length: 88 @@ -42,7 +43,10 @@ linters: # test-support package exists to hand a test privileges the program # itself must never have, so a file that is not a test must not import # one. Test files, and the files inside a package whose directory name - # ends in `test`, are where that code belongs, and are exempt. + # ends in `test`, are where that code belongs, and are exempt. A package + # in a subdirectory of that directory is not exempt. `${base-path}` is + # the directory holding this file, so the name of the directory a + # repository is cloned into does not count. # # The deny list below is the one part of this file a repository is # expected to extend, and the only part it may. depguard matches an @@ -57,24 +61,25 @@ linters: files: - "$all" - "!$test" - - "!**/*test/**" + - "!${base-path}**/*test/*" deny: - pkg: net/http/httptest desc: >- Test-support code belongs in test files and in packages whose directory name ends in test, not in the shipped binary. - # Only decisions already recorded in the Go package defaults are - # listed here. Every entry matches the module path exactly. + # Each entry names a module not to use and what to use instead. Every + # entry matches the module path exactly. gomodguard_v2: blocked: - module: github.com/rs/zerolog recommendations: - log/slog reason: "Structured logging is stdlib log/slog." - # One entry per pre-fork module path, because the later releases - # are separate paths. A prefix match would be shorter but would - # also reach github.com/go-redis/redismock, the test double for - # the successor these entries recommend. + # These entries cover only the github.com/go-redis/redis module paths, + # one entry per path, because the later releases are separate paths. + # A prefix match would be shorter but would also reach + # github.com/go-redis/redismock/v9, the test double for the successor + # these entries recommend. - module: github.com/go-redis/redis recommendations: - github.com/redis/go-redis/v9 @@ -87,6 +92,10 @@ linters: recommendations: - github.com/redis/go-redis/v9 reason: "Pre-fork module; use the maintained go-redis v9." + - module: github.com/go-redis/redis/v9 + recommendations: + - github.com/redis/go-redis/v9 + reason: "Pre-fork module; use the maintained go-redis v9." - module: github.com/sergi/go-diff recommendations: - github.com/aymanbagabas/go-udiff @@ -110,3 +119,4 @@ linters: issues: max-issues-per-linter: 0 max-same-issues: 0 + uniq-by-line: false diff --git a/TODO.md b/TODO.md index 49e890c..ba8678c 100644 --- a/TODO.md +++ b/TODO.md @@ -21,6 +21,27 @@ fmt-check, and commit. # Completed Steps +- 2026-11-03: The canonical golangci-lint is now v2.15.0, still built with + go1.27.0, so the `go` directive rule is unchanged (issue 142). Repositories + pick this up on their next re-vendor. Each item in the canonical + `.golangci.yml` was tried on a scratch module. These changed: + - `canonicalheader` is enabled again, because v2.15.0 fixes the random + misses behind issue 105. + - The `depguard` exemption covers only the files directly inside a directory + whose name ends in `test`. It used to reach every directory below that one + too. The name of the directory a repository is cloned into no longer + counts. + - `gomodguard_v2` also blocks `github.com/go-redis/redis/v9`, whose + pre-releases can still be imported under that path. + - `uniq-by-line` is now `false`, so a line that trips two linters reports + both findings. + - Three comments are corrected: + - `exhaustruct` is listed as deprecated. + - The test double is named `github.com/go-redis/redismock/v9`. + - The claim that every blocked module is in the Go package defaults is + gone. + - A comment says the file has no `formatters` section, so + `golangci-lint run` does not run `gofmt`. - 2026-11-03: A first test run that timed out now gets no verbose rerun (https://git.eeqj.de/sneak/prompts/issues/61), on sneak's approval at https://git.eeqj.de/sneak/prompts/issues/61#issuecomment-165195. The Go recipe diff --git a/prompts/REPO_POLICIES.md b/prompts/REPO_POLICIES.md index c075882..76a9e4a 100644 --- a/prompts/REPO_POLICIES.md +++ b/prompts/REPO_POLICIES.md @@ -698,10 +698,10 @@ style conventions are in separate documents: `test-support` depguard rule, where a repo names its own test-support packages by full import path. A repo adds entries there and changes nothing else, and a re-vendor carries its entries forward. The canonical golangci-lint version is - v2.14.0 (released 2026-09-24), pinned as the digest of the lint phase's base + v2.15.0 (released 2026-10-16), pinned as the digest of the lint phase's base image - (`golangci/golangci-lint@sha256:ad862ba6b3798cbe0fd9fd7408d498fd74fbd2623a92406b2fd3898faf0bf98f`, - which reports `2.14.0 built with go1.27.0 from 114493f9`). A module's `go` + (`golangci/golangci-lint@sha256:fbfcfd12a6f8d7f1b97b3362ca80fc2a244d46863148c73cb88e7793af96c481`, + which reports `2.15.0 built with go1.27.0 from 25c5369a`). A module's `go` directive must not name a newer Go minor version than the one golangci-lint was built with, or golangci-lint refuses to lint it: this release lints `go 1.27.1` but not `go 1.28`. That digest is the only pin, since no repo