What is A Golang Linter And How To Use It?

Reza Khademi
4 min readJan 20, 2024

--

What is A Golang Linter And How To Use It?

Using a Golang linter is a good practice when you start to developing your application.

We, as developers, try to write code that is simple and efficient. However, let’s be honest, we are human and during writing or reviewing our beloved codes, we sometimes forget to remove some unnecessary conditions, employ early return pattern, even notice when we have a shadowed variable.

A Golang linter (pretty much every linter in any programming language) goes beyond checking code styles. Actually it will help us to write better code, fewer conditions, optimizing system memory usage and reducing overall code complexity.

A Golang linter can assist us to us in defining a sound coding rules for nearly every step of coding of coding like: error handling, struct field alignment, prevent exhaustive code, log and dependency rules.

In this story, we will use a Golang Linter called golangci-lint which can integrate almost all community driven linters. It allows us to configure every step easily and integrates with editors such as VSCode, Goland, Vim and Atom.

All the configurations for this story can be accessed here.

Before anything we need to install golangci-lint and it’s one straightforward step: (choose one of the following commands)

# first way: binary will be $(go env GOPATH)/bin/golangci-lint
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.55.2

# alternative way: install it into ./bin/
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.55.2

# docker way:
docker run --rm -v $(pwd):/app -v ~/.cache/golangci-lint/v1.55.2:/root/.cache -w /app golangci/golangci-lint:v1.55.2 golangci-lint run -v

To ensure we installed Golang linter properly run this command:

golangci-lint --version

We should see something like:

Golang linter golangci-lint version command output
golangci-lint — version output

After that, the fun part begins. Open your favorite editor, navigate to your Golang project, and create a .golangci.yml file in the root directory to store all our configurations.

Every configuration file can have some major parts. A linters-settings section includes every linter rules customization. The linters section which we put linter names to make them enabled to analyze our codes. The run section is dedicated to tasks we want to execute after running the linter.

We can also add issues section also to prevent running linter on some specific files like: test files. Until now we have a .golangci.yml file like below:

how to use Golang linter with golangci lint
.golangci.yml file

We want to make a well-structured and opinionated config file, we start by setting disable-all: true in the linters section to enable each golang linter individually. Following that, we add some major and well-known linters to increase code reliability:

Let’s briefly examine some of above the linters mentioned above. For more you can read full documentation and details here.

  • asasalint prevent function from having []any as any in variadicfunc(…any) this will make sure our code behave more predictably and apart from the logger, we generally don’t need these kinds of function parameters in our program, so we will navigate to linters-settings section and exclude our log function parameters from being considered as bad code.
  • dupl linter will detect code duplication with a threshold of lines that we will determine on linters-settings.
  • errcheck linter will search our codes to find any unhandled error that can harm our application.
  • gosec check any potential security risk we have in our codes.
  • gomnd prevent any hard coded number in our code. e.g: 3 * time.Second
  • revive a very well, extensible and fast golang linter which let us define very strict presets for write better code. (read more here)
  • gocritic will review our codes for diagnostics, performance and style issues.

Let’s go forward and fill other section with desired settings like below:

By using above file we will prevent: misspelling, hard coded values, potential security issues, duplicate code and constant definition, potential nil pointer dereference, unused parameters, unwanted dependencies, unnecessary type conversion and system memory usage saving when defining struct field.

We will allow 3*time.Second only when it is used alongside context.WithTimeout(context.Background(), 3*time.Second) or in the math package, and …any in log functions.

We can run golangci-lint run command to see our code issues and fix them.

Golang Linter Editor Integration

You may integrate golangci-lint with your editor for instant feedback about your codes.

VSCode integration is so easy just put these in the json settings file:

"go.lintTool": "golangci-lint",
"go.lintFlags": [
"--fast"
]

# using it in an editor without --fast can freeze your editor.
# golangci-lint automatically discovers .golangci.yml config
# you don't need to configure it in VS Code settings.

If you are using Vim, Goland and other editor read here.

ALSO READ:

--

--