agentsclimarketplace

Go linting

Skill muratmirgun/gophers/skills/go-linting

26 production-grade Go skills for Claude Code, Gemini CLI, and opencode.

Install
npx -y skills add muratmirgun/gophers --skill go-linting

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when setting up linting for a Go project, configuring golangci-lint, picking a linter set, suppressing findings with //nolint, or wiring lint checks into CI. Apply proactively whenever a project lacks .golangci.yml, when lint output is unclear, or when a new package needs the project's quality bar. Does not cover code review process (see go-code-review).

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

7.6 KB, as published. Nobody here has run it

Go Linting

The single most important property of a linting setup is consistency: every contributor and every CI run uses the same rules. golangci-lint is the tool; a checked-in .golangci.yml is the contract.

Core Rules

  1. Every Go project has a .golangci.yml at the repository root. It is the source of truth for which linters run.
  2. Lint runs in CI on every PR. A green build means lint is green.
  3. Lint runs locally before commit. A pre-commit hook or make lint keeps the feedback loop fast.
  4. Suppress with reasons. //nolint:linter // why — never bare //nolint.
  5. Fix the cause first. A suppression should be the last resort, not the default reaction.
  6. Never silence security linters (gosec, bodyclose, sqlclosecheck) without a strong, documented reason.

Setup Procedure

  1. Install: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest (or brew install golangci-lint).
  2. Drop a baseline .golangci.yml at the repo root.
  3. Run golangci-lint run ./....
  4. Fix the findings in order — formatting first, govet next, style last.
  5. Re-run until clean. Commit .golangci.yml and any source fixes together.
  6. Add the CI workflow (see references/ci-integration.md).

Minimum Linter Set

These five catch the most common issues and have the lowest noise rate. Start here:

LinterCatches
errcheckUnchecked error returns
govetMistakes that compile but are wrong (printf args, shifts, etc.)
staticcheckBug-prone patterns, dead code, simplifications
ineffassignAssignments whose value is never read
reviveStyle issues (modern replacement for golint)

Add formatting on top: gofmt / goimports (or gofumpt for stricter rules). With golangci-lint v2 these run via golangci-lint fmt.

Recommended Additional Linters

Enable these once the baseline is clean:

LinterWhen to enable
gosecAny service that handles untrusted input
bodycloseAny code that calls http.Client.Do
sqlclosecheckAny code using database/sql
nilerrAny code that does if err != nil { return nil } style returns
misspellAlways — comments and strings
unconvertAlways — flags useless type conversions
nolintlintAlways — enforces the //nolint rules below
paralleltestIf most tests can use t.Parallel()
thelperIf you write test helpers (enforces t.Helper())
testifylintIf the project uses testify
gocyclo / gocognitWhen you want a complexity ceiling
exhaustiveWhen you use iota-based enums and want full switch coverage

Read references/linter-catalog.md when picking from the long tail of correctness, style, security, and complexity linters, or when deciding which ones to enable on legacy code.

Development Workflow

lint:
	golangci-lint run ./...

lint-fix:
	golangci-lint run --fix ./...

fmt:
	golangci-lint fmt ./...

ci-lint:
	golangci-lint run --new-from-rev=origin/main ./...
TaskCommand
Run all enabled lintersgolangci-lint run ./...
Auto-fix everything fixablegolangci-lint run --fix ./...
Format the tree (v2+)golangci-lint fmt ./...
Lint only changed codegolangci-lint run --new-from-rev=origin/main ./...
Run one lintergolangci-lint run --enable-only=govet ./...
Show which linters existgolangci-lint linters

--new-from-rev is what makes incremental adoption work: legacy code stays untouched, new and changed code must meet the bar.

Read references/ci-integration.md when wiring GitHub Actions, pre-commit hooks, or selective linting on PRs.

Suppressing Findings

// Good: specific linter + a reason
//nolint:errcheck // fire-and-forget; Sync error is not actionable on shutdown
_ = logger.Sync()
// Bad: blanket, no reason — nolintlint will flag this
//nolint
_ = logger.Sync()

Rules (enforced by nolintlint):

  • Name the linter: //nolint:errcheck, not //nolint.
  • Include a justification after //.
  • Place the directive on the same line as the finding, or immediately above the construct it applies to.
  • Prefer per-line suppressions over file-level //nolint:all.

Read references/nolint-directives.md when deciding between inline, block, and file-scope suppressions, or when reviewing existing //nolint for stale rationale.

Interpreting Output

Each finding looks like:

path/to/file.go:42:10: message describing the issue (linter-name)

The linter name in parentheses is the key — look it up in the catalog to see what it actually checks, then either fix the code or suppress with a reason that names the same linter.

Anti-Patterns

Anti-patternWhy it hurtsDo this instead
No .golangci.yml in the repoEach contributor lints differently or not at allCommit a baseline config; CI enforces it
//nolint with no linter nameDisables every check on that line, silently//nolint:errcheck // reason
//nolint:all at the top of a fileWhole file escapes reviewSuppress per construct with a reason
Lint failures non-blocking in CI"Green build" becomes meaninglessBlock merges on lint failure
Enabling 100 linters on day oneNoise drowns signal; team gives upStart with the minimum set, add gradually
Suppressing gosec / bodyclose without justificationSilently hides real bugsFix the cause; if you can't, document why in the suppression
Different lint versions in dev vs CI"Works on my machine" comes backPin the version in CI and document it in the README
Linting after the fact, only in CISlow iteration; PRs ping-pongRun locally via make lint or a pre-commit hook

Verification Checklist

Before merging a linting change:

  • .golangci.yml exists at the repo root and is checked in
  • golangci-lint run ./... is clean (or --new-from-rev reports no new issues)
  • CI runs golangci-lint and blocks merges on failure
  • nolintlint is enabled; no bare //nolint remains
  • Every //nolint includes a linter name and a one-line reason
  • Security linters (gosec, bodyclose, sqlclosecheck) are enabled where applicable

References

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.