golangci-lint
golangci-lint copied to clipboard
Debug why a private linter was not added to the list
Hi, I am using a private linter but it doesn't appear in the list of linters.
- I have checked the dependencies list to make sure all versions are the same as the golang ci 1.29 (http://github.com/alexisvisco/logwercase).
- My .golang-ci.yml is like that:
linters:
enable:
- unparam
- misspell
- godox
- gocritic
- scopelint
- golint
- unconvert
- gofmt
- exportloopref
- govet
- bodyclose
- gosimple
- goconst
- gosec
- logwercase
linters-settings:
custom:
logwercase:
path: /home/aviscogl/go/bin/logwercase.so
description: Analyze case of log message and WithField keys
original-url: github.com/alexisvisco/logwercase
There is an option to known why a private linter is not added? https://golangci-lint.run/contributing/debug/ Does not help me ...
Hey, thank you for opening your first Issue ! 🙂 If you would like to contribute we have a guide for contributors.
@alexisvisco thanks for your issue. I just quickly tried, seems like it's showing for me. Can you share your steps ?
$ ./golangci-lint linters
Enabled by your configuration linters:
...
gomnd: An analyzer to detect magic numbers. [fast: true, auto-fix: false]
goprintffuncname: Checks that printf-like functions are named with `f` at the end [fast: true, auto-fix: false]
gosec (gas): Inspects source code for security problems [fast: true, auto-fix: false]
gosimple (megacheck): Linter for Go source code that specializes in simplifying a code [fast: true, auto-fix: false]
govet (vet, vetshadow): Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string [fast: true, auto-fix: false]
ineffassign: Detects when assignments to existing variables are not used [fast: true, auto-fix: false]
interfacer: Linter that suggests narrower interface types [fast: true, auto-fix: false]
lll: Reports long lines [fast: true, auto-fix: false]
logwercase: Analyze case of log message and WithField keys [fast: true, auto-fix: false]
misspell: Finds commonly misspelled English words in comments [fast: true, auto-fix: true]
nakedret: Finds naked returns in functions greater than a specified function length [fast: true, auto-fix: false]
$ ./golangci-lint linters | grep -is logwercase
logwercase: Analyze case of log message and WithField keys [fast: true, auto-fix: false]
Strange, I was not using the right config, unfortunately, it does not work as you because I get an output from golangci:
ERRO Unable to load custom analyzer logwercase:/home/aviscogl/go/bin/logwercase.so, plugin: not implemented
I don't know why it's outputting that because you were able to add it :thinking:
Might be related to version. I used master branches with one small changes to make sure same x/tools version in your tool and golangci-lint. With your above config, I just ran the check.
Can you share version details as well?
I was pretty sure the exact same versions are present...
golangci-lint has version 1.29.0 built from 6a68907 on 2020-07-20T14:54:31Z
You are right, seems like there is some issue with v1.29.0. I didn't see any related commits, which could affect this one.
Can you try with master branches (in golangci-lint and in your logwercase) as well ?
I am experiencing the same behavior.
When I build golangci-lint from the master branch (60613dc3eb841f9d3a07dcc2c59e96eefdfc428f) my custom plugin works just fine.
When I use the docker images for versions 1.27, 1.28, and 1.29, I get the plugin: not implemented error.
Update: I just built from the v1.29.0 tag and everything worked fine. I wonder if the problem might be in the way the release binary is being created? Something that disables plugin use?
This might be related: https://github.com/golang/go/issues/19569
Looks like CGO_ENABLED is the culprit.
| golangci-lint | my plugin | result |
|---|---|---|
| CGO_ENABLED=1 | CGO_ENABLED=1 | Success |
| CGO_ENABLED=0 | CGO_ENABLED=1 | Failure plugin: not implemented |
| CGO_ENABLED=1 | CGO_ENABLED=0 | Cannot build plugin loadinternal: cannot find runtime/cgo |
| CGO_ENABLED=0 | CGO_ENABLED=0 | Cannot build plugin loadinternal: cannot find runtime/cgo |
So custom plugins will never work with release versions because the release binary is compiled with CGO_ENABLED=0 Same goes for the docker images, since they also use a CGO_ENABLED=0 binary.
However, the docker images could work if the golangci-lint binary in them was compiled with CGO_ENABLED=1 Then users could create their own docker images which extend the golang-ci image and add the custom plugins as well. Note that the custom plugins should probably be compiled as part of the build process for the customized docker image, to avoid using plugins which were created for different architectures (darwin)
@mattysweeps thanks for your detailed explaination. You are right, the release binaries are built with CGO_ENABLED=0 only. This might be something we can improve.
Should the binary produced during the installation of golanci-lint not by default support plugins since it is a feature of the linter?
Should the binary produced during the installation of golanci-lint not by default support plugins since it is a feature of the linter?
Yeah, I am completely agreed with you. Just found related issue here https://github.com/golangci/golangci-lint/issues/1182 though.
@alexisvisco seems like there is nothing we can do here, except update docs :). Please let me know if it's fine.
@alexisvisco seems like there is nothing we can do here, except update docs :). Please let me know if it's fine.
I encountered the same problem when dealing with golangci-lint custom plugin feature.
so for private linter, we have to build the golangci-lint with CGO_ENABLED=1 flag from source code to leverage this feature. But I think the extra step breaks the feature since the purpose of go plugin is to load packages without rebuilding the main binary. If we have to rebuild it, why not create a intree plugin instead of the custom one. Please correct me if there's something wrong. :)
@sayboras correct me, if I wrong, please. If I want to use a private plugin I need to compile golangci with CGO_ENABLED=1 by myself? And I need to compile it on the docker image I use in my CI and for all platforms, my team uses for development?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
From #1182 and https://github.com/golangci/golangci-lint/issues/1276#issuecomment-665903858 it seems clear that building from source with CGO_ENABLED is the only way to use custom linters, and that any custom linter must be built with the same set of dependencies and Go version as golangci-lint was built with.
Is there any "supported" way to use plugins with a release build? As the bug report template shows,
Yes, I'm using a binary release within 2 latest major releases. Only such installations are supported.
However, if the only supported releases cannot be used with custom linters, does this imply that custom linters are not supported? Might it be possible to add CGO_ENABLED=1 binaries to the release pipeline in addition so that users have access to a "supported" release that can be used with custom linters?
Is there any "supported" way to use plugins with a release build?
It's not possible because of how Go plugins work.
However, if the only supported releases cannot be used with custom linters, does this imply that custom linters are not supported?
In an issue template, you have to be short, the goal is to say that we don't support old versions.
Custom linters are supported by their authors.
The custom linters "system" is supported by the golangci-lint team.
It's not possible because of how Go plugins work.
Could you expand on this more (maybe I should open a separate discussion for this)?
As I understand it, Go plugins have a number of requirements in order to be loaded as described in #3259. If a binary release was built with CGO_ENABLED=1, wouldn't that allow linter authors to write plugins and use them with that binary, provided they meet those constraints in their plugin development?
This just caught me out after following guide for new-linters which doesn't mention that the release binaries are incompatible with this, making support for plugins a little mute as consumers will always need to create a custom build of golangci-lint.
Has there been any thoughts on creating release builds with CGO_ENABLED=1?
It is not working for me, although I'm using a self-compiled version go golangci-lint (master version).
I followed the description here: https://golangci-lint.run/contributing/new-linters/#how-to-add-a-private-linter-to-golangci-lint (which does not mention at all that the release builds are not working with private linters)
Used the example linter referenced in the doc and configured the config with:
custom:
example:
path: /absolute/path/to/example.so
description: The description of the linter
original-url: github.com/golangci/example-linter
'example' does not appear in the list of golangci-lint linters. GL_DEBUG=loader gives no hint that something is wrong in the config.
Any ieads why the tutorial is not working for me? Help is appreciated.
@stevenh I've opened https://github.com/golangci/golangci-lint/discussions/3361 to discuss this since it seems like this issue is not the recommended place to discuss it. Posting this comment here just to let people know that it exists and direct them there.
Unassigned myself due to lack of cycles.