Skip to content

Commit 06456a9

Browse files
committed
Update Code
1 parent 4fe84ce commit 06456a9

File tree

2 files changed

+65
-82
lines changed

2 files changed

+65
-82
lines changed

README.md

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,64 @@
1-
This is an example linter that can be compiled into a plugin for `golangci-lint`.
2-
3-
To use this:
4-
5-
### Create the Plugin From This Linter
6-
7-
1. Download the code \*
8-
2. From the root project directory, run `go build -buildmode=plugin plugin/example.go`.
9-
3. Copy the generated `example.so` file into your project or to some other known location of your choosing. \**
10-
11-
12-
### Create a Copy of `golangci-lint` that Can Run with Plugins
13-
(After the PR this will be either the production code or simpler to get hopefully. For now atleast, you must build this locally because it needs code that hasn't been accepted yet. Additionally, `golangci-lint` is built with the vendors option, which breaks plugins that have overlapping dependencies, so a vendor-free version of the code must be used)
14-
15-
1. Download the `i473` branch of https://github.com/dbraley/golangci-lint/tree/i473
16-
2. From that projects root directy, run `make vendor_free_build`
17-
3. Copy the `golangci-lint` executable that was created to your path, project, or other location
18-
19-
### Configure Your Project for Linting
20-
21-
1. If the project you want to lint does not have one already, copy the https://github.com/dbraley/golangci-lint/blob/i473/.golangci.yml to the root directory.
22-
2. Adjust the yaml to appropriate `linters-settings:custom` entries as so:
23-
```
24-
linters-settings:
25-
custom:
26-
example: # If this doesn't match the linters name definition, it will warn you but still run
27-
path: /example.so # Adjust this the location of the plugin
28-
enabled: true # This determines if the linter is run by default
29-
original-url: github.com/dbraley/example-linter # This is just documentation for custom linters
30-
slow: false # Set this to true to observe `--fast` option
31-
```
32-
3. If your `.golangci.yml` file has `linters:disable-all` set to true, you'll also need to add your linter to the `linters:enable` seciont:
33-
```
34-
linters:
35-
enable:
36-
# ...
37-
- varcheck
38-
- whitespace
39-
# Custom linters
40-
- example
41-
```
42-
4. Alternately, you can leave it disabled and turn it on via command line only: `golangci-lint run -Eexample`
43-
5. If everything works correctly, you should see the linter show up as enabled by running `golangci-lint linters`. This linter will look for `// TODO: ` in front of functions, so you can also add that to your code and see the errors.
44-
6. You can also see the linter get loaded with the `-v` option for either `run` or `linters`
45-
46-
### To Configure Your Own `golang.org/x/tools/go/analysis` Based Linter
47-
48-
Your Linter must implement one or more `analysis.Analyzer` structs.
49-
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`.
50-
51-
You'll also want to create a go file like `plugin/example.go`. This MUST be in the package `main`, and define:
52-
1. A variable of type `analyzerPlugin`. The type `analyzerPlugin` can be defined as a string, struct, whatever.
53-
```
54-
type analyzerPlugin struct{}
55-
var AnalyzerPlugin analyzerPlugin
56-
```
57-
2. A function with signature `func (*analyzerPlugin) GetLinterName() string`
58-
3. A function with signature `func (*analyzerPlugin) GetLinterDesc() string`
59-
4. A function with signature `func (*analyzerPlugin) GetAnalyzers() []*analysis.Analyzer`
60-
61-
\* Sorry, I haven't found a way to enable `go get` functionality for plugins yet. If you know how, let me know!
62-
63-
\** Alternately, you can use the `-o /path/to/location/example.so` output flag to have it put it there for you.
1+
This is an example linter that can be compiled into a plugin for `golangci-lint`.
2+
3+
To use this:
4+
5+
### Create the Plugin From This Linter
6+
7+
1. Download the source code \*
8+
2. From the root project directory, run `go build -buildmode=plugin plugin/example.go`.
9+
3. Copy the generated `example.so` file into your project or to some other known location of your choosing. \**
10+
11+
12+
### Create a Copy of `golangci-lint` that Can Run with Plugins
13+
14+
In order to use plugins, you'll need a golangci-lint executable that can run them. The normal version of this project
15+
is built with the vendors option, which breaks plugins that have overlapping dependencies.
16+
17+
1. Download [golangci-lint](https://github.com/golangci/golangci-lint) source code
18+
2. From the projects root directory, run `make vendor_free_build`
19+
3. Copy the `golangci-lint` executable that was created to your path, project, or other location
20+
21+
### Configure Your Project for Linting
22+
23+
If you already have a linter plugin available, you can follow these steps to define it's usage in a projects
24+
`.golangci.yml` file. An example linter can be found at [here](https://github.com/golangci/example-plugin-linter). If you're looking for
25+
instructions on how to configure your own custom linter, they can be found further down.
26+
27+
1. If the project you want to lint does not have one already, copy the [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) to the root directory.
28+
2. Adjust the yaml to appropriate `linters-settings:custom` entries as so:
29+
```
30+
linters-settings:
31+
custom:
32+
example:
33+
path: /example.so
34+
description: The description of the linter
35+
original-url: github.com/golangci/example-linter
36+
```
37+
38+
That is all the configuration that is required to run a custom linter in your project. Custom linters are enabled by default,
39+
but abide by the same rules as other linters. If the disable all option is specified either on command line or in
40+
`.golang.yml` files `linters:disable-all: true`, custom linters will be disabled; they can be re-enabled by adding them
41+
to the `linters:enable` list, or providing the enabled option on the command line, `golangci-lint run -Eexample`.
42+
43+
### To Create Your Own Custom Linter
44+
45+
Your linter must implement one or more `golang.org/x/tools/go/analysis.Analyzer` structs.
46+
Your project should also use `go.mod`. All versions of libraries that overlap `golangci-lint` (including replaced
47+
libraries) MUST be set to the same version as `golangci-lint`. You can see the versions by running `go version -m golangci-lint`.
48+
49+
You'll also need to create a go file like `plugin/example.go`. This MUST be in the package `main`, and define a
50+
variable of name `AnalyzerPlugin`. The `AnalyzerPlugin` instance MUST implement the following interface:
51+
```
52+
type AnalyzerPlugin interface {
53+
GetAnalyzers() []*analysis.Analyzer
54+
}
55+
```
56+
The type of `AnalyzerPlugin` is not important, but is by convention `type analyzerPlugin struct {}`. See
57+
[plugin/example.go](https://github.com/golangci/example-plugin-linter/plugin/example.go) for more info.
58+
59+
To build the plugin, from the root project directory, run `go build -buildmode=plugin plugin/example.go`. This will create a plugin `*.so`
60+
file that can be copied into your project or another well known location for usage in golangci-lint.
61+
62+
\* Sorry, I haven't found a way to enable `go get` functionality for plugins yet. If you know how, let me know!
63+
64+
\** Alternately, you can use the `-o /path/to/location/example.so` output flag to have it put it there for you.

plugin/example.go

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,18 @@
22
package main
33

44
import (
5-
"fmt"
65
linters "github.com/dbraley/example-linter"
76
"golang.org/x/tools/go/analysis"
87
)
98

109
type analyzerPlugin struct{}
1110

12-
func main() {
13-
fmt.Printf("Plugin library for %s", AnalyzerPlugin.GetLinterName())
14-
fmt.Println("To compile this into a plugin, run:")
15-
fmt.Println(" go build -buildmode=plugin -o /desired/path/to/example.so plugin/example.go")
16-
fmt.Println("See README.md for more info")
17-
}
18-
19-
// This must be implemented
20-
func (*analyzerPlugin) GetLinterName() string {
21-
return "example"
22-
}
23-
24-
// This must be implemented
25-
func (*analyzerPlugin) GetLinterDesc() string {
26-
return "A package of custom linters that can be used in golangci-lint"
27-
}
28-
2911
// This must be implemented
3012
func (*analyzerPlugin) GetAnalyzers() []*analysis.Analyzer {
3113
return []*analysis.Analyzer{
3214
linters.TodoAnalyzer,
3315
}
3416
}
3517

36-
// This must be defined
18+
// This must be defined and named 'AnalyzerPlugin'
3719
var AnalyzerPlugin analyzerPlugin

0 commit comments

Comments
 (0)