|
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. |
0 commit comments