deprecated reflect mode has been replaced with import mode#198
deprecated reflect mode has been replaced with import mode#198tulzke wants to merge 0 commit intouber-go:mainfrom
Conversation
There was a problem hiding this comment.
Hey! Thank you for this PR! We're excited about this change. We took a first pass and have some initial comments. We're going to do some additional testing on this and come back soon for more review.
One high level comment I wanted to raise was - with Go 1.23, go/types introduced Alias. Can we add test cases that try to load aliases to interfaces and verify this will work?
This already works without explicitly specifying an alias. This works thanks to the Underlying method. Example of generated mock for alias: mock/mockgen/internal/tests/import_mode/mock/interfaces.go Lines 297 to 434 in 703a35f And, yes, i tested it in compile-time: Generated mock successfully implements alias. |
@tulzke, when I run mockgen's tests on go1.23.1, or with GODEBUG=gotypesalias=1, I get the following failure: This is because |
|
Forgot to add - since |
Why we can't just update go up to 1.23 in go.mod? This is the latest stable version. If we make different implementations for different versions of Go, it will be noticeably more difficult to maintain. |
I'm gonna ask other maintainers their thoughts here because I'm actually not super sure myself. cc: @sywhang @r-hang @tchung1118. I believe using 1.23 in go.mod would force anybody who wants to use the next release to upgrade to go1.23. We can technically bump the version of |
|
As moving to go1.23 would be considered a breaking change, it might make sense to release as v2 which would force users to move forward manually. That would allow the old system to work with older versions but force users to move forward with a "modern" version. I've been watching/waiting/using this change for a few weeks now. For users that want to stay up-to-date with Go versions and latest protoc changes, not merging this change is causing real headaches. |
This change updates all `go.mod` and ci workflows to only support go1.22 and go1.23. Although this will force users to upgrade to go1.22 to use the next release, it is technically in line with our release policy (see: https://github.com/uber-go/mock?tab=readme-ov-file#supported-go-versions) and will allow us to merge uber-go#198 without using build tags for references to the new `*types.Alias` and `types.Unalias()`.
|
Chatted about build tags vs. go.mod update internally - we think it's fine to update This is technically in line with our release policy and will avoid some ugly code in the big switch statement as @tulzke mentioned.
As a policy, we don't typically do 2.0 releases. If something is truly a breaking change we don't usually even consider it. In this case however - I'm not sure dropping support for Go versions that aren't even supported themselves upstream qualifies as a breaking change, so I think it's fine to update |
This change updates all `go.mod` and ci workflows to only support go1.22 and go1.23. Although this will force users to upgrade to go1.22 to use the next release, it is technically in line with our release policy (see: https://github.com/uber-go/mock?tab=readme-ov-file#supported-go-versions) and will allow us to merge #198 without using build tags for references to the new `*types.Alias` and `types.Unalias()`.
ci/test.sh
Outdated
| #!/bin/bash | ||
| # This script is used to ensure that the go.mod file is up to date. | ||
|
|
||
| # Compatibility for Go 1.22 |
There was a problem hiding this comment.
Can you expand on why this is needed? Ideally, we'd want to support Go 1.22 w/o the GODEBUG variable set.
There was a problem hiding this comment.
I have already generated mocks for aliases. Without gotypesalias=1, mocks are generated without aliases.
Example from failed test:
< func (c *MockEarthHumanPopulationCall) Return(arg0 int) *MockEarthHumanPopulationCall {
---
> func (c *MockEarthHumanPopulationCall) Return(arg0 import_mode.HumansCount) *MockEarthHumanPopulationCall {
HumansCount here - alias for int. On 1.23 and 1.22 with GODEBUG=gotypealias=1 mockgen wiil generate mocks with correct types. On native 1.22 it wil generate int instead of import_mode.HumansCount.
Tests on 1.22 and 1.23 have different behavior now due to aliases.
There was a problem hiding this comment.
Understood - let's keep this here then. Can you just add this brief explanation into the test script?
There was a problem hiding this comment.
I have tested it now. And with go 1.22 in go mod it does not work with aliases as i expected.
$ go version
go version go1.23.1 darwin/arm64
$ cat go.mod | grep "go 1."
go 1.22
$ cd mockgen
$ go build . && cp mockgen /Users/USERNAME/go/bin/mockgen # copy binary to PATH
$ cat internal/tests/import_mode/go.mod | grep "go 1." #checking go version in nested go module
go 1.23
$ cd internal/tests/import_mode
$ cat interfaces.go| grep "AddHumans"
AddHumans(HumansCount) []Human
$ go generate ./...
$ cat mock/interfaces.go | grep "AddHumans(arg0" #must have HumansCount and Human instead of int and Primate
func (m *MockEarth) AddHumans(arg0 int) []import_mode.Primate {
func (mr *MockEarthMockRecorder) AddHumans(arg0 any) *MockEarthAddHumansCall {In my case it works only after i changed go version in go.mod and rebuild binary.
Do you have any ideas how to support go 1.22 and alias types together?
|
Hey @tulzke - I'm sorry, I mistakenly overrode your remote branch's I think I'm able to re-instate it/re-open the PR how it was by pushing the correct |
I can't re-open this PR, so i created the new one: |
resolves #175
resolves #197
resolves #128
It is impossible to create an mock for a generic interface via reflect mode, because it is impossible to compile a generic type without instantiation.
This PR replaces the reflect mod for parsing using go/types.
All exists mocks have been regenerated and the tests have been passed. But since this radically changes the behavior of reflect mode, I would be grateful if there are those who want to add additional test cases that I did not provide.
We can also come up with another name instead of import mode.
benefits: