Skip to content

[build] Enable golangci-lint #2766

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

Merged
merged 32 commits into from
Nov 5, 2020
Merged

[build] Enable golangci-lint #2766

merged 32 commits into from
Nov 5, 2020

Conversation

linasm
Copy link
Collaborator

@linasm linasm commented Oct 19, 2020

What this PR does / why we need it:
WIP golangci-lint

Special notes for your reviewer:
Added depguardagainst imports:

      github.com/golang/protobuf/jsonpb: "replace with github.com/gogo/protobuf/jsonpb"
      google.golang.org/protobuf/encoding/protojson: "replace with github.com/gogo/protobuf/jsonpb"
      github.com/golang/protobuf/proto: "replace with github.com/gogo/protobuf/proto"
      google.golang.org/protobuf/proto: "replace with github.com/gogo/protobuf/proto"

Does this PR introduce a user-facing and/or backwards incompatible change?:
NONE

Does this PR require updating code package or user-facing documentation?:
NONE

@linasm linasm changed the title [build] Enable golangci-lint WIP [build] Enable golangci-lint Oct 19, 2020
@linasm linasm marked this pull request as ready for review October 20, 2020 08:02
@linasm linasm changed the title WIP [build] Enable golangci-lint [build] Enable golangci-lint Oct 20, 2020
@mway mway self-requested a review October 26, 2020 15:04
Copy link
Collaborator

@mway mway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good!

.golangci.yml Outdated
lll:
# max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 120
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go with 100. I'd rather use 80, honestly, but 100 seems like a good compromise.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to both

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will change to 100.

# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on defaulting this to true? We probably shouldn't allow unused exported identifiers except in special situations (and generally we should be referencing things we're using, even if only in tests), especially if we're trying to be intentional about API surface area.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does referencing the exported type from a test in the same package prevent the check from firing?

I think the false-positives from text editor integrations makes this a pain to enable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'd like to avoid is blindly exporting types that aren't actually being used to avoid API bloat, such that we catch exported types that can't be proven to be used in some capacity (or otherwise, //nolint them).

I use vanilla vim (I know, I'm a masochist), so I can't comment on workarounds for editors, but off the cuff I'd rather have our linting be defined by goal state rather than by issues/limitations with editor(s).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mway I agree that this would be a nice option in general.
But somewhat unexpetedly, after enabling it I'm getting messages on test functions everywhere:

(...)
src/aggregator/aggregator/flush_mgr_test.go:36:6: func `TestFlushManagerReset` is unused (unused)
src/dbnode/client/session_fetch_tagged_test.go:406:6: func `TestSessionFetchTaggedMergeWithRetriesTest` is unused (unused)
src/query/graphite/common/basic_functions_test.go:97:6: func `TestNormalize` is unused (unused)
(...)

Also, I believe we have a need to treat some pieces of this code base as a library, which would become complicated with this option. Leaving it at 'false` at least for now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yeah, I see what you mean. If we were able to skip test files for that specific linter, that seems like it would help, but if we're just going to get a bunch of noise because it doesn't understand that they're tests, agree that this isn't great.

I wonder whether it behaves differently in _test packages, which I think we should be using more broadly in general (although obviously not the case here in general, and probably wouldn't help us for the majority of the lint noise).

Makefile Outdated
Comment on lines 228 to 232
lint: export GO_BUILD_TAGS = $(GO_BUILD_TAGS_LIST)
lint: install-tools linter
@echo "--- :golang: Running linters"
./scripts/run-ci-lint.sh $(tools_bin_path)/golangci-lint
./bin/linter ./...
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this able to run by subdir?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, will do.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

late to the party, but running by subdir multiplies the runtime by # of subdirs you have, and defeats most of golangci-lint optimizations (only parsing code once).
this should not be a default mode of operation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in #2863

@@ -35,8 +35,10 @@ steps:
run: app
workdir: /go/src/github.com/m3db/m3
<<: *common
- name: "Services, Tools, Metalint"
command: make clean install-vendor-m3 services tools metalint
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are services and tools not relevant any more?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

# options for analysis running
run:
# default concurrency is a available CPU number
# concurrency: 4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we enable this? Don't suppose there's some way to take this from an env var so that we can run CI with high concurrency?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can override this on the command line for CI

skip-dirs:
- generated/.*
# There is some very weird golangci-lint bug that causes analysis to fail on the
# eventlog_server_test.go file (perhaps caused by https://github.com/golangci/golangci-lint/issues/995).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did any of the suggestions in that thread help here?

depguard:
list-type: blacklist
include-go-root: false
packages:
Copy link
Collaborator

@arnikola arnikola Nov 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the other assert package that gets autoimported sometimes? I believe it's github.com/tj/assert, trying to remember if there's a similar issue for require but think it's ok

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, adding github.com/tj/assert.

check-exported: false
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 30
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit; worth making this 1? I think we generally want to discourage naked returns considering we don't really use them anywhere and they're a lot harder to reason about

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reducing nesting, typically via early returns, is outlined in Uber's Go Style Guide:

Code should reduce nesting where possible by handling error cases/special conditions first and returning early or continuing the loop. Reduce the amount of code that is nested multiple levels.

Otherwise, we end up with a greater amount of indentation in aggregate, which isn't ideal.

# True by default.
simple: true
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we enable this one too?

Comment on lines +200 to +201
# Linter that checks that every comment ends in a period.
- godot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this only affect godoc or all comment? If it's godoc only may be worth enabling

Copy link
Collaborator

@arnikola arnikola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me with nits on other linters to attempt

@linasm
Copy link
Collaborator Author

linasm commented Nov 5, 2020

@mway, @arnikola I've implemented most of your suggestions.
Given the usual controversies around linter settings (and trying to avoid "perfect is the enemy of done"), I suggest to land this, and continue any further discussion/fine tuning of specific settings as a separate effort.

Copy link
Collaborator

@mway mway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pushing this through!

@linasm linasm merged commit 5a3a12b into master Nov 5, 2020
@linasm linasm deleted the linasm/golangci-lint branch November 5, 2020 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants