Intro
If you program in Go, you probably have used the built-in linter, the go vet ./...
, this linter is good and catches some common issues, but today we will explore some alternatives, and the chosen one was golangci-lint
.
golangci-lint
isn’t a linter; it is a collection of linters. Over 70 linters on it will point you from code style inconsistencies to nasty bugs.
As the name suggests, it is built to run on a continuous integration environment and is fast!
Examples of issues found
cmd/web/main.go:47:3: exitAfterDefer: os.Exit will exit, and
defer cancel()
will not run (gocritic) os.Exit(1)
This one a good example that may lead to serious problems of memory leaks and resource leaks.
internal/model/user.go:15:13: G404: Use of weak random number generator (math/rand instead of crypto/rand) (gosec) number := uint(rand.Uint64())
This one is good advice to use good random number generators.
pkg/errors/errors.go:14:74:
occured
is a misspelling ofoccurred
(misspell) ErrUnexpected = &Error{Code: 9999, Err: errors.New(“an unexpected error occured”)}
It is always good to fix all spelling, this tool also catches missing periods for example.
Running locally
golangci-lint, like many Go projects, is a single binary. You can download it and put it into /usr/local/bin
, it is also possible to install it using brew.
There are other methods, please refer to this page to check out.
My preferred method is through Docker:
docker run -t --rm -v $(pwd):/app -w /app golangci/golangci-lint golangci-lint run
If you want to use all linters and possibly catch all issues, run with the flag --enable-all
. Be prepared, because this tool takes serious code smell and possible sources of bugs.
Your project must have a
go.mod
and at least one source code, likemain.go
, for the tool runs.
Using it on GitHub Action
To run in an Action on GitHub it is pretty simple, just add the contents below to a file named .github/workflows/lint.yml
.
name: golangci-lint
on:
push:
tags:
- v*
branches:
- master
- main
pull_request:
permissions:
contents: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.19
- name: Checkout
uses: actions/checkout@v3
- name: Lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
Please refer to the full documentation for more details.
Conclusion
Having lint in your tool belt is always a good idea; having multiple linters is even better.