-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: new custom linters system #4437
Conversation
FYI The failure of the CI is expected because it's just a POC. |
@pohly I'm interested in your feedback about this new way to use plugins. |
I like this design. I've been using a custom binary (the manual way, more or less) that I hacked to load my own plugins. From reading this PR, I'm confident it will cover my current use case without having to resort to hacks. It would be nice to have a way for |
With this POC you can generate a binary called I prefer to keep the thing separated: one command to run, one command to build. Maybe the vscode-go plugin can offer an option to handle the binary (name, path, etc.) |
That makes sense. Once this change lands I can submit a PR to vscode-go to detect |
9549ea8
to
6fb922a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. I've been proposing a similar mechanism myself elsewhere, without knowing about this SQL driver precedent.
I'm not sure whether we would use this in Kubernetes, though: we already rebuild in the CI from source, so building the Go plugin in the same environment is not a burden. Because we build with go install
, adding a file to the build would be more complicated than what we do now.
I'm aware that go install
is not recommended. It has been working so far.
@bombsimon do you have an opinion about this PR? |
I don't have much experience with how a plugin interface would look like without re-building so with that in mind this looks fine to me. But it also makes me feel, if shelling out to I'm also curious about the decision to bootstrap and build Either way, the current plugin system is crap and this is a great initiative! I don't have any better suggestion and it seems to satisfy users who requested this! 👍 I'm also not sure it solves #3669 because that requests to run plugins without re-building |
The goal of an official way to build plugins is just to simplify the usage and provide something stable, but you can do the same manually with different approaches.
I don't remember the "check the version" topic 🤔 From my memory, the call to external resources was to get something not controlled by golangci-lint or a public source of trust, and updatable at runtime. Here, we rely on GitHub (only for the golangci-lint repo) and Go proxies, they are not perfect sources of trust but at least it's manageable from the point of view of the security. At least, this approach is more secure than the current Go plugin system https://twitter.com/dominikhonnef/status/1394766501157167112
During the creation of Yaegi, I experimented with multiple interpreters. Currently, we already embedded an interpreter: Also we (the We can also talk about WASM (I also worked on a WASM plugin integration in Go), but IMHO it's not ready to be used inside something like golangci-lint. |
Thanks for elaborating, it sounds like you've given this a lot of though and considered the alternatives! I'm mostly asking because once this lands I guess it will be a part of I think a wasm solution could be interesting to explore as well. I've seen projects like https://github.com/knqyf263/go-plugin which seems pretty cool although I didn't dig much deeper to see how relevant it is. But also speaking of the linked inspiration by HashiCorp that seems pretty well tested, have you had any look to see if something like https://github.com/hashicorp/go-plugin would fit? It looks pretty nice to run the plugin in a subprocess and use rpc communication. But looking at this poc implementation there doesn't seem to be a lot to maintain and I don't have any concrete alternative or relevant experience so don't interpret my questions as if I'm not for this suggestion - I'm all for it and just want to bounce some alternatives. Btw do you plan to deprecate the current plugin system closely after or will they live in parallel? |
This kind of plugin is extremely slow (from the POV of golangci-lint) but it's not the main problem. Like the other ways to create plugins, the pros and cons depend on the usage context, there is no silver bullet. golangci-lint needs a high-performance extension system and easy maintenance.
The 2 plugin systems can live together, and they don't require a lot of maintenance. |
0b14054
to
493c019
Compare
The PR is now ready for review. The 2 first commits are the POC and the revert of the POC commit, then you can ignore them. The other commits contain one focused change by commit (I hope easy to review). The doc is far from perfect but I think it's a good start. The new module To test the PR
version: feat/new-plugin-module
name: custom-golangci-lint
plugins:
- module: 'github.com/golangci/example-plugin-module-linter'
version: v0.1.0
linters-settings:
custom:
example:
type: module
description: Example
original-url: github.com/golangci/example-plugin-module-linter
settings:
one: Foo
two:
- name: Bar
three:
name: Bar
linters:
disable-all: true
enable:
- example
|
c5f6bde
to
49880c0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⭐
1e9470b
to
a9102e5
Compare
aadfab3
to
e13d2fa
Compare
It's time to merge this PR 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for noise 🙏
Cool job.
I just found you implemented this @ldez, it's amazing it will change the way we had to work with the home-made plugin. We might have to rewrite a lot of things, but at least we will avoid the iterative fix we had You make my day @ldez Thanks !!! I will take a look at https://github.com/golangci/example-plugin-module-linter More to come here https://github.com/synthesio/zconfigcheck/ for our https://github.com/synthesio/zconfig lib |
We know the complaints about custom linter with the Go plugin system.
Today if you want to use a plugin, you have to:
golangci-lint
from sources withCGO_ENABLED=1
golangci-lint
The problems are:
golangci-lint
and the plugins build with the same stack.And I will cite the Go documentation:
For me, it's clear that the Go plugin system is not adapted to extend golangci-lint.
I propose to use a different approach that follows the Go recommendation, the principle is similar to SQL drivers in Go:
init
to register itself.Description of the previous POC
This PR is a POC to discuss the custom linters.
The idea comes during the rewrite of the commands and the
Manager
.We know the complaints about custom linter with the Go plugin system.
Today if you want to use a plugin, you have to:
golangci-lint
from sources withCGO_ENABLED=1
golangci-lint
The problems are:
golangci-lint
and the plugins build with the same stack.And I will cite the Go documentation:
For me, it's clear that Go plugin system is not adapted to extend golangci-lint.
I propose to use a different approach that follows the Go recommendation, the principle is similar to SQL drivers in Go:
init
to register itself.FYI I already created something similar on https://github.com/kvtools/valkeyrie.
I put
how-to.md
andreadme.md
inside the directorypkg/experimental
and its subdirectories.There is a new command:
golangci-lint custom
If we want to follow this way we can either keep the command inside
golangci-lint
or use it as an external tool (inside the org).The idea is to place the configuration file
.mygcl.yml
into a project that requires a plugins and then just rungolangci-lint custom
.A binary
gcl-custom
will be automatically built and placed where the command has been run.You should read the file
pkg/experimental/how-to.md
for more details.Fixes #4427
Fixes #2505
Fixes #1276
Maybe a fix for #3669, #3826, #2566