-
-
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: apply formatters after the suggested fixes #5246
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ldez
force-pushed
the
feat/formatters
branch
from
December 24, 2024 12:01
8a76e20
to
8a0dd0c
Compare
Thanks for the clear status. It was indeed a problem to explain these behaviors |
ccoVeille
reviewed
Dec 24, 2024
ldez
force-pushed
the
feat/formatters
branch
from
December 24, 2024 13:50
636293c
to
74f0e0c
Compare
Nothing to be sorry about, thank you for the details description and examples making it easy to understand 😃 |
bombsimon
reviewed
Dec 25, 2024
alexandear
reviewed
Dec 25, 2024
bombsimon
approved these changes
Dec 25, 2024
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.
LGTM!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Sorry for the long description, but I want to be sure to provide all the information to understand the context.
Inside golangci-lint there are 4 "linters" that are not real linters/analyzers but "formatters":
gofmt
,goimports
,gofumpt
, andgci
.Their standard outputs are
[]byte
and notDiagnostic
, internally golangci-lint produces diff patches based on[]byte
and converts them intoDiagnostic
.Also
goimports
andgci
are not "import formatters": they format all the code and not only imports.Problems
All those tools provide the same base functionality (format) with some variants but their changes could be incompatible (mainly on imports) unless they are run in a specific order and without incompatible settings.
Incompatibilities
gofmt
+gci
-> potential problem on importsgoimports
+gci
-> potential problem on importsgofumpt
+gci
-> potential problem on importsgofmt
+goimports
-> potential problem on importsgofumpt
+goimports
-> potential problem on importsgofmt
+gofumpt
-> potential problem on imports, and on function signaturesI solved the main problem on imports with the support of suggested fixes: if a conflict is detected, only the suggested fixes of one linter are applied and a warning is displayed for the others.
But this has some side effects, and it can be handled differently.
Identical but Different
The real problem is that each formatter has specificities, there is no "winner".
gofmt
goimports
gofumpt
gci
goimports
is a "variant" ofgofmt
withoutsimplify
andrewrite-rules
but withlocal-prefixes
to organize imports.gofumpt
is a "variant" ofgoimports
withextra-rules
, andmodule-path
is more limited thanlocal-prefixes
.gci
is a "variant" ofgoimports
with options to customize import orders.Note:
gci
has a terrible name because this is an acronym of golangci(-lint) instead of something related to "imports". I think we should evaluate asking for a renaming.The PR
I don't want to recommend a formatter over another because each formatter has specificities.
With this PR, they will behave like a linter (reports) but suggested fixes will be skipped, be run after the fixing process, and be used in a specific order.
The specific order is:
gofmt
gofumpt
goimports
gci
This will allow applying all the changes, in one run, and without any conflicts.
Note, this doesn't mean I recommend using all those linters at the same time, it's the opposite, in the majority of cases, only one or two of those formatters is needed.
But golangci-lint should be able to provide a consistent output even in those unwanted situations.
Example
I will illustrate the topic with a terribly wrong configuration, nobody should do that: I will use, at the same time, all the options of all formatters even the conflicting options.
.golangci.yml
main.go
In this example, there are several rules that should be applied:
goimports
,gofumpt
,gci
)interface{}
should be replaced byany
(gofmt
)Bar
should be changed to remove the "duplicate" type. (gofumpt
)Currently (v1.62), you must run golangci-lint 2 times and hope to be lucky:
gofmt
replacements are applied but the imports are duplicated because of a "fight" between all linters. Also, this is a "lucky case" because in some cases some imports can disappear.gofumpt
appliesextra-rules
and the imports are fixed (by one of the linters).With the PR about suggested fixes, you must run golangci-lint 3 times but there are no unexpected changes (no import duplication or removal):
goimports
will be applied (no import duplication)gci
andgofumpt
are appliedgofmt
replacements are applied.With this PR, you only need one run:
$ ./golangci-lint run --fix $