-
-
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
make decorder
usable
#3138
Comments
Hey, thank you for opening your first Issue ! 🙂 If you would like to contribute we have a guide for contributors. |
Hello,
Yes, it's the expected behavior.
A lot of users use |
Sorry, no. As is it's unexpected behavior. I expected that linter to require 2 mental hops:
It is unexpected and frustrating that in fact obtaining any findings requires two more mental hops:
Alas, my proposition was intended towards a |
Sorry, but it's the behavior that I expect for this opinionated linter. We can change a linter configuration without creating a v2. golangci-lint is a meta-linter that requires choosing and configuring linters. |
I'm not saying it's unexpected to the maintainer. I'm saying it's unexpected to a user. As a user, I install a meta-linter. I take a look at a list of disabled linters. Say a line catches my eye:
Now I enable this linter. I expect it to check declaration order. It's not out of this earth, it literally promises me that, right there. As of now, it does absolutely nothing. |
I just want to explain a bit more why, for me, this linter is way too much opinionated and in some way wrong. Case 1: Methods and types linters-settings:
decorder:
disable-dec-num-check: true
disable-dec-order-check: false
disable-init-func-first-check: true Beforepackage cli
type Yo struct {
Foo string `description:"Foo description"`
Fii string `description:"Fii description"`
Fuu string `description:"Fuu description"`
Yi *Yi `label:"allowEmpty" file:"allowEmpty"`
Yu *Yi
}
func (y *Yo) SetDefaults() {
y.Foo = "foo"
y.Fii = "fii"
}
type Yi struct {
Foo string
Fii string
Fuu string
}
func (y *Yi) SetDefaults() {
y.Foo = "foo"
y.Fii = "fii"
} cli/fixtures_test.go:16:1: type must not be placed after func (decorder)
type Yi struct {
^ Afterpackage cli
type Yo struct {
Foo string `description:"Foo description"`
Fii string `description:"Fii description"`
Fuu string `description:"Fuu description"`
Yi *Yi `label:"allowEmpty" file:"allowEmpty"`
Yu *Yi
}
type Yi struct {
Foo string
Fii string
Fuu string
}
func (y *Yo) SetDefaults() {
y.Foo = "foo"
y.Fii = "fii"
}
func (y *Yi) SetDefaults() {
y.Foo = "foo"
y.Fii = "fii"
} Splitting Struct types and methods is not a good practice: this will decrease the readability and maintainability. Case 2: Grouping types linters-settings:
decorder:
disable-dec-num-check: false
disable-dec-order-check: true
disable-init-func-first-check: true Beforepackage cli
type Yo struct {
Foo string `description:"Foo description"`
Fii string `description:"Fii description"`
Fuu string `description:"Fuu description"`
Yi *Yi `label:"allowEmpty" file:"allowEmpty"`
Yu *Yi
}
func (y *Yo) SetDefaults() {
y.Foo = "foo"
y.Fii = "fii"
}
type Yi struct {
Foo string
Fii string
Fuu string
}
func (y *Yi) SetDefaults() {
y.Foo = "foo"
y.Fii = "fii"
} cli/fixtures_test.go:11:1: multiple "type" declarations are not allowed; use parentheses instead (decorder)
type Yi struct {
^ Afterpackage cli
type (
Yo struct {
Foo string `description:"Foo description"`
Fii string `description:"Fii description"`
Fuu string `description:"Fuu description"`
Yi *Yi `label:"allowEmpty" file:"allowEmpty"`
Yu *Yi
}
Yi struct {
Foo string
Fii string
Fuu string
}
)
func (y *Yo) SetDefaults() {
y.Foo = "foo"
y.Fii = "fii"
}
func (y *Yi) SetDefaults() {
y.Foo = "foo"
y.Fii = "fii"
} Grouping Struct types without their methods is not a good practice: this will decrease the readability and maintainability. Case 3: Grouping constants linters-settings:
decorder:
disable-dec-num-check: false
disable-dec-order-check: true
disable-init-func-first-check: true Beforepackage cli
// Code of Bar.
const (
CodeBarA = 100
CodeBarB = 101
)
// Status of Foo.
const (
StatusFooA = "A"
StatusFooB = "B"
) cli/foo.go:10:1: multiple "const" declarations are not allowed; use parentheses instead (decorder)
const (
^ Afterpackage cli
const (
CodeBarA = 100
CodeBarB = 101
StatusFooA = "A"
StatusFooB = "B"
) Even with an empty line, we have lost the meaning of the const groups. Once again this is bad practice. I will not list all the problems related to this strongly opinionated linter. I can understand that some people want to follow this linter, but by default, we cannot suggest bad practices. Note:
|
Thank you for illustrating this so well! For the cases 2 and 3 I can only agree. This is why I began with My intended usage was a variant of your case 1 but with added enforcement of max one |
Your feature request related to a problem? Please describe.
Currently, when a user adds the
decorder
linter the default configuration makes the linter silently ignore all its findings.Consider cognitive load. For a vaguely interested user, it's already a hop to find a relevant linter in the list. Enabling that linter is another hop. Frustratingly, nothing happens. Learning about per-linter configs would be the 3rd hop and configuring this specific linter is the 4th hop.
Let's skip hops 3 and 4.
Describe the solution you'd like.
Change the above defaults for
decorder
in a major release (v2) to:(Leaving the first one
true
as it was, but it's only a subjective suggestion.)Describe alternatives you've considered.
Change the defaults for
decorder
in a minor v1.x release. This doesn't impact users who run the default set of linters, becausedecorder
isn't one. There are however users who enabledecorder
and such a minor version upgrade would very likely get them new findings.Additional context.
Example of the findings under the new settings:
The text was updated successfully, but these errors were encountered: