Linting Golang projects

Why should I use a lint?

  • Readability
  • Maintainability
  • Help the code review process
  • Avoid (syntax) issues
  • Ensure stiles and standards
  • Following the good practices

Linter for Golang

I’d like to suggest to use:

To Install

# 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.30.0

golangci-lint --version

More info and options: https://golangci-lint.run/usage/install/

To Run

Use GitHub Actions to integrate it with your CI

See its demonstration: https://github.com/dev4devs-com/lintpoc/pull/2/files

How to Configure

Add in the root directory of your project the .golangci.yml file with its rules:

Check it in the lintpoc project: https://github.com/dev4devs-com/lintpoc/blob/master/.golangci.yml

How to enable it on the CI with GitHub Actions:

Create the file `.github/workflows/golangci-lint.yml` with the following content. It will use the configuration in the root directory and will perform the checks.

name: golangci-lint
on:
  push:
    tags:
      - v*
    branches:
      - master
  pull_request:
jobs:
  golangci:
    name: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v1
        with:
          # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
          version: v1.29

          # Optional: working directory, useful for monorepos
          # working-directory: somedir

          # Optional: golangci-lint command line arguments.
          # args: --issues-exit-code=0

          # Optional: show only new issues if it's a pull request. The default value is `false`.
          # only-new-issues: true

Suggestion: Configure it to allow you check the lint locally via Makefile:

lint: golangci-lint ## Run golint
	@$(GOLANGCI_LINT) run

To install the lint in the bin/ dir of the project:

golangci-lint:
ifeq (, $(shell which golangci-lint))
	@{ \
	set -e ;\
	curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.29.0 ;\
	}
GOLANGCI_LINT=$(shell go env GOPATH)/bin/golangci-lint
else
GOLANGCI_LINT=$(shell which golangci-lint)
endif

**NOTE:** It is NOT a good practice commit binaries. In this way, do not forget to add in the .gitignore:

bin/*

Tips

Use the flag –fix to automatically fix some checks and issues:

golangci-lint run --fix

See that you can setup this helper in your Makefile as well:

lint-fix: golangci-lint ## Run golint fix
	@$(GOLANGCI_LINT) run --fix

How to ignore the false positives and to deal with exceptions:

To ignore specific checks into specific areas of your code :

// nolint:<checkName>

Example:

Also, you can perform configurations in the .golangci.yml to ignore directories, files and etc. Also, it can be very specific such as; for the check N in the files A,B,C ignore the errors with “X” see:

Demo Project:

The following project was created to help you with and let you know how it works. Feel free to check:

https://github.com/dev4devs-com/lintpoc

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s