-
-
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
Add iface linter #4871
Add iface linter #4871
Conversation
In order for a pull request adding a linter to be reviewed, the linter and the PR must follow some requirements.
Pull Request Description
Linter
The Linter Tests Inside Golangci-lint
|
@uudashr please don't edit the message. |
@uudashr stop editing the message or you will be kicked off the organization. |
Sorry, reverting the message |
You edited the message once again and reverted all my changes to the message... |
As long as the elements required by the checklist (except those related to maintainer actions) are not handled, the review will not start. Don't edit the checklist! |
This comment was marked as off-topic.
This comment was marked as off-topic.
This could lead to false positive because an empty interface can be used on purpose.
This leads to false positive because you can provide interface shared by other packages to avoid duplication. Note: it's not "the package" but "a package"
This leads to false positive with extended interfaces. type a interface {
// ...
}
type b interface {
a
} Note: it's not "the package" but "a package"
This leads to false positives because a library can provide an interface without implementation to extend the behavior. |
Correct. Thanks for pointing this out. I've seen some library use If we define We can use Any suggestion? The linter still able to help us raising awareness so we can make an extra consideration when using empty interface.
I'm taking below statements as consideration:
I would love to have
Why you want to do that? Technically Go allow us to pollute our code with interfaces, but again the questions is why you want to do that? If we have very large package that host many concepts, having duplicate package is possible. But then you might want to consider breakdown the package into more specific concept, the duplication is less likely.
This is related to function that hides the concrete value, for example type Server interface {
Server() error
}
func NewServer(addr string) Server { // will report warning
return &serverImpl{addr: addr}
} So we suggest to just return the concrete exported struct. But below code is valid, no warning will be reported. It has possibility to return more than one implementation. type Server interface {
Server() error
}
func NewServer(addr string) Server { // will not report warning
if strings.HasPrefix(addr, "secure:") {
return &secureServer{addr: addr}
}
return &server{addr: addr}
} |
My remarks were based on real projects with legitimate usages. The theory is great but it should not be turned into a dogma 😉 About For me, this rule is the only one in which false positives are niche. About When you are designing a complex library, providing an interface in a separate package can be required for several reasons:
About
Because of readability: complex things require to be named to be easy to maintain. About I will repeat but a library can provide an interface without implementation to extend the behavior. |
About
This looks valid. Made me think to take out this one. Thanks man. 👍 Not many people will use empty interface unless they might really need it. If this linter really insist to be exist, will not much useful either. About
If you have reference, a project or real example on this, I would love to continue my research on what should we do to avoid interface pollution.
FYI the linter won't yield warning to About
Been thinking of this before to justify whether the linter is not necessary to be exists. But hardly find real example on this. If you have some, please drop me a the repo link. About
The linter would not yield warning due to this.
I'm not sure this is relate to Well I might need to rephrase the description of the analyzer, here it is: "identifies functions returning interfaces when the actual return value is always a single concrete implementation". It is related to "factory function" mentioned Avoid Interface Pollution |
I updated your PR to ease the detection of false-positives. |
If you want an example of a lib with an interface but no implementation (except for tests): https://github.com/kvtools/valkeyrie/blob/017bb9979d23d57c439c6f24b724ed5625c40f1e/store/store.go#L12 An example of false-positive with You can take a look of the "Details" section here: ldez/golangci-lint-bench#14 (comment) |
You have reverted all my changes and did a bad rebase. I fixed what I could but please avoid that. |
Sorry of that, my bad.
Thanks for the fix. Sure do I need to catch up with huge master diff, I do confuse myself having this big rebase.
Thanks for this, I use this and made some changes with same goal. |
The problem was not a "huge master diff/big rebase" but the fact that you didn't pull my changes before modifying the code locally despite my message notifying you about this change. I fixed the rebase but my previous code has been deleted. |
d048bd8
to
9cc3432
Compare
I fixed:
But this is only to illustrate my opinion with real world examples. My opinion is still the same:
For real-world examples, see the "Details" section here. |
thanks, let me check for those each projects |
You will not be able to fix something because it's related to the nature of your linters. The best and only way is to change the default to disable |
I see. Let me change those |
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
Add new linter "iface" to help discover and avoid interface pollution
Linter link: https://github.com/uudashr/iface