golangci-lint icon indicating copy to clipboard operation
golangci-lint copied to clipboard

Debug why a private linter was not added to the list

Open alexisvisco opened this issue 5 years ago • 16 comments

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 ...

alexisvisco avatar Jul 28 '20 12:07 alexisvisco

Hey, thank you for opening your first Issue ! 🙂 If you would like to contribute we have a guide for contributors.

boring-cyborg[bot] avatar Jul 28 '20 12:07 boring-cyborg[bot]

@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]

sayboras avatar Jul 28 '20 12:07 sayboras

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:

alexisvisco avatar Jul 28 '20 14:07 alexisvisco

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?

sayboras avatar Jul 28 '20 14:07 sayboras

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

alexisvisco avatar Jul 28 '20 14:07 alexisvisco

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 ?

sayboras avatar Jul 29 '20 11:07 sayboras

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?

mattysweeps avatar Jul 29 '20 19:07 mattysweeps

This might be related: https://github.com/golang/go/issues/19569

mattysweeps avatar Jul 29 '20 19:07 mattysweeps

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 avatar Jul 29 '20 20:07 mattysweeps

@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.

sayboras avatar Jul 30 '20 11:07 sayboras

Should the binary produced during the installation of golanci-lint not by default support plugins since it is a feature of the linter?

alexisvisco avatar Jul 31 '20 08:07 alexisvisco

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.

sayboras avatar Jul 31 '20 12:07 sayboras

@alexisvisco seems like there is nothing we can do here, except update docs :). Please let me know if it's fine.

sayboras avatar Aug 08 '20 03:08 sayboras

@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. :)

draveness avatar Sep 24 '20 08:09 draveness

@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?

AlwxSin avatar Mar 24 '21 07:03 AlwxSin

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.

stale[bot] avatar Mar 30 '22 06:03 stale[bot]

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?

ian-h-chamberlain avatar Oct 27 '22 17:10 ian-h-chamberlain

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.

ldez avatar Oct 27 '22 17:10 ldez

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?

ian-h-chamberlain avatar Oct 27 '22 18:10 ian-h-chamberlain

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?

stevenh avatar Nov 06 '22 19:11 stevenh

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.

mibo-fdc avatar Nov 19 '22 15:11 mibo-fdc

@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.

ian-h-chamberlain avatar Nov 22 '22 14:11 ian-h-chamberlain

Unassigned myself due to lack of cycles.

sayboras avatar Dec 13 '22 13:12 sayboras