$npx -y skills add samber/cc-skills-golang --skill golang-lintLinting best practices and golangci-lint configuration for Golang projects — running linters, configuring .golangci.yml, suppressing warnings with nolint directives, interpreting lint output, and selecting linters. Use when configuring golangci-lint, asking about lint warnings or
| 1 | **Persona:** You are a Go code quality engineer. You treat linting as a first-class part of the development workflow — not a post-hoc cleanup step. |
| 2 | |
| 3 | **Orchestration mode:** Use `ultracode` when adopting linting on a legacy codebase — orchestrate the five sub-agents described in the "Parallelizing Legacy Codebase Cleanup" section (auto-fix, security linters, error handling, style/formatting, code quality) so independent linter categories are fixed concurrently. |
| 4 | |
| 5 | **Modes:** |
| 6 | |
| 7 | - **Setup mode** — configuring `.golangci.yml`, choosing linters, enabling CI: follow the configuration and workflow sections sequentially. |
| 8 | - **Coding mode** — writing new Go code: launch a background agent running `golangci-lint run --fix` on the modified files only while the main agent continues implementing the feature; surface results when it completes. |
| 9 | - **Interpret/fix mode** — reading lint output, suppressing warnings, fixing issues on existing code: start from "Interpreting Output" and "Suppressing Lint Warnings"; use parallel sub-agents for large-scale legacy cleanup. |
| 10 | |
| 11 | **Dependencies:** |
| 12 | |
| 13 | - golangci-lint: `go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest` |
| 14 | |
| 15 | # Go Linting |
| 16 | |
| 17 | ## Overview |
| 18 | |
| 19 | `golangci-lint` is the standard Go linting tool. It aggregates 100+ linters into a single binary, runs them in parallel, and provides a unified configuration format. Run it frequently during development and always in CI. |
| 20 | |
| 21 | Every Go project MUST have a `.golangci.yml` — it is the **source of truth** for which linters are enabled and how they are configured. See the [recommended configuration](./assets/.golangci.yml) for a production-ready setup with 48 linters enabled. |
| 22 | |
| 23 | ## Quick Reference |
| 24 | |
| 25 | ```bash |
| 26 | # Run all configured linters |
| 27 | golangci-lint run ./... |
| 28 | |
| 29 | # Auto-fix issues where possible |
| 30 | golangci-lint run --fix ./... |
| 31 | |
| 32 | # Format code (golangci-lint v2+) |
| 33 | golangci-lint fmt ./... |
| 34 | |
| 35 | # Run a single linter only |
| 36 | golangci-lint run --enable-only govet ./... |
| 37 | |
| 38 | # List all available linters |
| 39 | golangci-lint linters |
| 40 | |
| 41 | # Verbose output with timing info |
| 42 | golangci-lint run --verbose ./... |
| 43 | ``` |
| 44 | |
| 45 | ## Configuration |
| 46 | |
| 47 | The [recommended .golangci.yml](./assets/.golangci.yml) provides a production-ready setup with 33 linters. For configuration details, linter categories, and per-linter descriptions, see the **[linter reference](./references/linter-reference.md)** — which linters check for what (correctness, style, complexity, performance, security), descriptions of all 33+ linters, and when each one is useful. |
| 48 | |
| 49 | ## Suppressing Lint Warnings |
| 50 | |
| 51 | Use `//nolint` directives sparingly — fix the root cause first. |
| 52 | |
| 53 | ```go |
| 54 | // Good: specific linter + justification |
| 55 | //nolint:errcheck // fire-and-forget logging, error is not actionable |
| 56 | _ = logger.Sync() |
| 57 | |
| 58 | // Bad: blanket suppression without reason |
| 59 | //nolint |
| 60 | _ = logger.Sync() |
| 61 | ``` |
| 62 | |
| 63 | Rules: |
| 64 | |
| 65 | 1. **//nolint directives MUST specify the linter name**: `//nolint:errcheck` not `//nolint` |
| 66 | 2. **//nolint directives MUST include a justification comment**: `//nolint:errcheck // reason` |
| 67 | 3. **The `nolintlint` linter enforces both rules above** — it flags bare `//nolint` and missing reasons |
| 68 | 4. **NEVER suppress security linters** (gosec, bodyclose, sqlclosecheck) without a very strong reason |
| 69 | |
| 70 | For comprehensive patterns and examples, see **[nolint directives](./references/nolint-directives.md)** — when to suppress, how to write justifications, patterns for per-line vs per-function suppression, and anti-patterns. |
| 71 | |
| 72 | ## Development Workflow |
| 73 | |
| 74 | 1. **Linters SHOULD be run after every significant change**: `golangci-lint run ./...` |
| 75 | 2. **Auto-fix what you can**: `golangci-lint run --fix ./...` |
| 76 | 3. **Format before committing**: `golangci-lint fmt ./...` |
| 77 | 4. **Incremental adoption on legacy code**: set `issues.new-from-rev` in `.golangci.yml` to only lint new/changed code, then gradually clean up old code |
| 78 | |
| 79 | Makefile targets (recommended): |
| 80 | |
| 81 | ```makefile |
| 82 | lint: |
| 83 | golangci-lint run ./... |
| 84 | |
| 85 | lint-fix: |
| 86 | golangci-lint run --fix ./... |
| 87 | |
| 88 | fmt: |
| 89 | golangci-lint fmt ./... |
| 90 | ``` |
| 91 | |
| 92 | For CI pipeline setup (GitHub Actions with `gol |