-
-
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 gofactory
linter
#4196
base: master
Are you sure you want to change the base?
Add gofactory
linter
#4196
Conversation
Hey, thank you for opening your first Pull Request ! |
7799b5c
to
14c0aba
Compare
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
|
Maybe to combine with check from #3488? |
I don't want to combine |
2. Added tests 3. Added config 4. Added linter
14c0aba
to
70cd3e5
Compare
Is there anything else that I can do to get the PR be approved and merged? |
bf7fb06
to
5a86fb8
Compare
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.
Thanks for the linter!
In addition to review comments:
TestdataDir()
->analysistest.TestData()
- Case like
type OtherStruct struct {}
type Struct struct {
Other OtherStruct
}
func NewStruct() Struct {
return Struct{
Other: OtherStruct{}, // warning?
}
}
Type assertion, type declaration and type underlying, tests <- Broken link
- Struct with type params?
type Struct[T any] struct { // type params could be many (this is different ast node)
}
_ = Struct[T]{} // Warning
- Import alias (and affect on report warning?).
- You covered slice, but not map, channel, func call, etc. places where obj could be constructed.
2. Added test with options
# golangci/golangci-lint#4196 1. TestdataDir() -> analysistest.TestData() 2. Described False-Negative cases as testcases and in README.md 3. Fixed link for type_nested.go.skip in README.md 4. Added testcase with generic 5. Added testcase with alias 6. Added testcase with map, chan, array, func # golangci/golangci-lint#4196 7. Added glob syntax for pkgs 8. Renamed options 9. Extended unexpected code message 10. Added unimplemented testcases
Could I resolve the case on Winter Weekends, not now?)
|
Just a reminder for the maintainers: before reviewing the code, the checklist should be handled. |
The use of the tests dedicated to linters that need dependencies is not the right way. I'm not sure about the pertinence of this linter because Go doesn't require constructors, and data structure is a good pattern, I think this will lead to a lot of false positives. |
Do you mean tests should be like this and remove subdirectories? package gofactory
import "net/http"
func local() {
_ = http.Request{} // want...
_, _ = http.NewRequest("GET", "http://example.com", nil)
} |
My motivation was to create the linter for the domain layer with business logic in the factories, which cannot be skipped and where any structures should always be valid. I agree that using the go-factory-lint in any place is not a good idea, so I added options Should I force set |
2. Removed nested directory in test
I removed subdirectories in tests. I'm not sure what you mean. I can't because the linter needs this to determine whether it is a function or a type when we cast types like this. package casting
import (
"factory/unimplemented/casting/nested"
)
func ToNestedMyInt() {
_ = nested.MyInt(1) // want `Use factory for nested.Struct`
} |
2. renamed options 3. changed linter version
@@ -137,7 +137,7 @@ func TestCgoOk(t *testing.T) { | |||
"--timeout=3m", | |||
"--enable-all", | |||
"-D", | |||
"nosnakecase,gci", | |||
"nosnakecase,gci,gofactory", |
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.
I hope that is correct solution to pass tests.
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.
your tests are not in the right places.
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.
Do you mean I should move test/testdata/gofactory/blocked.go
to test/testdata/gofactory/gofactory_package_globs_only.go
?
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.
no, your tests must be inside test/testdata/
and not a dedicated folder.
and your linter should be removed from test/linters_test.go
.
@@ -355,7 +355,6 @@ func TestLineDirectiveProcessedFiles(t *testing.T) { | |||
func TestUnsafeOk(t *testing.T) { | |||
testshared.NewRunnerBuilder(t). | |||
WithNoConfig(). | |||
WithArgs("--enable-all"). |
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.
how does this change relate to PR?
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.
If I return, can I add -D gofactory
to fix linter error Use factory for unsafe.Pointer
.
Or is solution from comment is better?
#4196 (comment)
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.
this should be reverted.
@@ -137,7 +137,7 @@ func TestCgoOk(t *testing.T) { | |||
"--timeout=3m", | |||
"--enable-all", | |||
"-D", | |||
"nosnakecase,gci", | |||
"nosnakecase,gci,gofactory", |
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.
need to rollback
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.
I added because of linter error Use factory for unsafe.Pointer
.
Should I add option to exclude checking of std libraries in gofactory?
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.
Should I add option to exclude checking of std libraries in gofactory?
Nice idea, but I think in case of exclude-std=false
we will receive false positive anyway, because a lot of std types could be (or must be) used without factory by design. Like unsafe.Pointer
or sync.Mutex
.
Zero value is useful 🙂
Look at
$ cd $GOROOT/src
$ gofactory -json ./... | jq '.[] | .[] | .[] .message' | sort | uniq
func call(_ http.Request) {} | ||
|
||
func alias() { | ||
_ = alias_blocked.Request{} // want `Use factory for http.Request` |
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.
cosmetic question: why not Use factory for alias_blocked.Request
?
at fist time I was confused, but cannot decide what option is better 🤔
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.
Idk too)
Could you decide how to better based on your experience?
I checked wrapcheck, go-reassign. They both used different printing way for package names.
I don't find another linter which uses package names.
wrapcheck: error returned from external package is unwrapped: sig: func encoding/json.Marshal(v any) ([]byte, error)
go-reassign: reassigning variable EOF in other package alias
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.
IMHO, the option that is better for grep and common understanding – to keep the source code and warnings for it consistent:
_ = neturl.URL{} // want `Use factory for neturl.URL`
_ = &url.URL{} // want `Use factory for url.URL`
The linter checks that the structures are created by the factory, and not directly.
The checking helps to provide invariants without exclusion and helps avoid creating an invalid object.
related to #2708