Table of Contents
How to write a custom linter
Use go/analysis
and take a look at this tutorial: it shows how to write go/analysis
linter
from scratch and integrate it into golangci-lint
.
How to add a public linter to golangci-lint
You need to implement a new linter using go/analysis
API.
We don't accept non go/analysis
linters.
After that:
- Implement functional tests for the linter:
- Add one file into directory
test/testdata
. - Run
T=yourlintername.go make test_linters
to ensure that test fails. - Run
go run ./cmd/golangci-lint/ run --no-config --disable-all --enable=yourlintername ./test/testdata/yourlintername.go
- Add one file into directory
- Add a new file
pkg/golinters/{yourlintername}.go
. Look at other linters in this directory. Implement linter integration and check that test passes. - Add the new struct for the linter (which you've implemented in
pkg/golinters/{yourlintername}.go
) to the list of all supported linters inpkg/lint/lintersdb/manager.go
to the functionGetAllSupportedLinterConfigs
.- Add
WithSince("next_version")
, wherenext_version
must be replaced by the next minor version. (ex: v1.2.0 if the current version is v1.1.0)
- Add
- Find out what options do you need to configure for the linter.
For example,
nakedret
has only 1 option:max-func-lines
. Choose default values to not being annoying for users of golangci-lint. Add configuration options to:- .golangci.reference.yml - the example of a configuration file. You can also add them to .golangci.yml if you think that this project needs not default values.
- config struct -
don't forget about
mapstructure
tag for proper configuration files parsing by pflag.
- Take a look at the example of Pull Request with new linter support.
How to add a private linter to golangci-lint
Some people and organizations may choose to have custom-made linters run as a part of golangci-lint
.
Typically, these linters can't be open-sourced or too specific.
Such linters can be added through Go's plugin library.
For a private linter (which acts as a plugin) to work properly,
the plugin as well as the golangci-lint binary needs to be built for the same environment. CGO_ENABLED
is another requirement.
This means that golangci-lint
needs to be built for whatever machine you intend to run it on
(cloning the golangci-lint repository and running a CGO_ENABLED=1 make build
should do the trick for your machine).
Configure a Plugin
If you already have a linter plugin available, you can follow these steps to define it's usage in a projects
.golangci.yml
file. An example linter can be found at here. If you're looking for
instructions on how to configure your own custom linter, they can be found further down.
- If the project you want to lint does not have one already, copy the .golangci.yml to the root directory.
- Adjust the yaml to appropriate
linters-settings:custom
entries as so:
linters-settings:custom:example:path: /example.sodescription: The description of the linteroriginal-url: github.com/golangci/example-linter
That is all the configuration that is required to run a custom linter in your project.
Custom linters are disabled by default, and are not enabled when linters.enable-all
is specified.
They can be enabled by adding them the linters.enable
list, or providing the enabled option on the command line (golangci-lint run -Eexample
).
Create a Plugin
Your linter must implement one or more golang.org/x/tools/go/analysis.Analyzer
structs.
Your project should also use go.mod
. All versions of libraries that overlap golangci-lint
(including replaced
libraries) MUST be set to the same version as golangci-lint
. You can see the versions by running go version -m golangci-lint
.
You'll also need to create a go file like plugin/example.go
. This MUST be in the package main
, and define a
variable of name AnalyzerPlugin
. The AnalyzerPlugin
instance MUST implement the following interface:
type AnalyzerPlugin interface {GetAnalyzers() []*analysis.Analyzer}
The type of AnalyzerPlugin
is not important, but is by convention type analyzerPlugin struct {}
. See
plugin/example.go for more info.
To build the plugin, from the root project directory, run go build -buildmode=plugin plugin/example.go
. This will create a plugin *.so
file that can be copied into your project or another well known location for usage in golangci-lint.