Skip to content
This repository has been archived by the owner on Jun 27, 2023. It is now read-only.

mockgen always tries to pull latest version instead of required version(go.mod without vendor) in docker golang:1.13 #354

Closed
tocrafty opened this issue Dec 13, 2019 · 8 comments · Fixed by #390

Comments

@tocrafty
Copy link

docker image: golang:1.13
go version: go1.13.5
gomock version: all after v1.1.0
gomock work mode: reflect mode

However, in OSX, without docker, mockgen works well with go.mod. Very strange!

@minicuts
Copy link
Contributor

minicuts commented Jan 7, 2020

@tocrafty That sounds that you invoked the go run in a different directory than in the one that contains go.mod

Can you share a reproducer? There are many edge cases to using mockgen with modules. And the behavior is quite subtle (especially when you are not explicitly setting the GO111MODULE might change in the future)

@codyoss codyoss added status: needs more info This issue need more information from the author. and removed status: investigating labels Jan 10, 2020
@tocrafty
Copy link
Author

tocrafty commented Jan 21, 2020

This is a test to reproduce the bug.

mockgen_test is a simple project with only one golang interface III which has two methods g() and f(). There are two commits in master branch. The commit before master has only one method f().

To mock the interface III, I start a new project with two files:

// go.mod
module test_mockgen
go 1.13

require (
        github.com/tocrafty/mockgen_test v0.0.0-20191213124124-4cc03a747f1f
)

and

# Makefile
mockgen_version ?= latest

.PHONY: docker
docker:
        docker run --rm \
                -v $(shell pwd):/mockgen \
                -w /mockgen \
                golang:1.13 \
                make no-docker out=out-docker.go mockgen_version=$(mockgen_version)

.PHONY: no-docker
no-docker: out = out.go
no-docker: mockgen
        # make sure we are in directory with go.mod
        @echo $(shell ls -al go.mod)
        # print the expect mockgen_test version in go.mod
        @grep "github.com/tocrafty/mockgen_test" go.mod

        # make sure GO11MODULE is on
        GO111MODULE=on mockgen github.com/tocrafty/mockgen_test III > $(out)

        # if we got a mocked function g(), it means mockgen used a wrong version of mogckgen_test.
        @if grep "g()" $(out); then \
                echo "used wrong version"; \
        else \
                echo "ok"; \
        fi

.PHONY: mockgen
mockgen:
        GO111MODULE=on go get github.com/golang/mock/mockgen@$(mockgen_version)

make no-docker gives ok(it runs locally on my osx). mockgen_version=v1.1.0 make docker also gives ok. However, any version after v1.1.0 all give used wrong version. The output of make docker indicated that mockgen always tried to pull latest version of mockgen_test.

➜ make docker
docker run --rm \
		-v /Users/yanbo/data/tmp/golang/mockgen:/mockgen \
		-w /mockgen \
		golang:1.13 \
		make no-docker out=out-docker.go mockgen_version=latest
GO111MODULE=on go get github.com/golang/mock/mockgen@latest
go: finding github.com/golang/mock v1.3.1
go: downloading github.com/golang/mock v1.3.1
go: extracting github.com/golang/mock v1.3.1
go: downloading golang.org/x/tools v0.0.0-20190425150028-36563e24a262
go: extracting golang.org/x/tools v0.0.0-20190425150028-36563e24a262
go: finding golang.org/x/tools v0.0.0-20190425150028-36563e24a262
# make sure we are in directory with go.mod
-rw-r--r-- 1 root root 154 Jan 21 07:19 go.mod
# print the expect mockgen_test version in go.mod
	github.com/tocrafty/mockgen_test v0.0.0-20191213124124-4cc03a747f1f
# make sure GO11MODULE is on
GO111MODULE=on mockgen github.com/tocrafty/mockgen_test III > out-docker.go
go: finding github.com/tocrafty/mockgen_test latest
go: downloading github.com/tocrafty/mockgen_test v0.0.0-20191213124830-295cf4692195
go: extracting github.com/tocrafty/mockgen_test v0.0.0-20191213124830-295cf4692195
# if we got a mocked function g(), it means mockgen used a wrong version of mogckgen_test.
func (m *MockIII) g() {
func (mr *MockIIIMockRecorder) g() *gomock.Call {
used wrong version

@codyoss codyoss removed the status: needs more info This issue need more information from the author. label Jan 22, 2020
@minicuts
Copy link
Contributor

I can reproduce this. Let me look into this.

@minicuts
Copy link
Contributor

minicuts commented Jan 22, 2020

Let me layout the root cause of the bug. I don't have a fix yet - I need to think a bit more what approach to take.

When we are reflecting a module/package (in your case mockgen_test) we are running so called prog.go program. There are possibly several attempts to run prog.go program in different directories. The first attempt is to run it in the the same directory as the input package (here is the code https://github.com/golang/mock/blob/master/mockgen/reflect.go#L156 ) The problem with that approach is, that when modules are used, that first attempt is to run the prog.go in module cache .../mod/pkg/... . And thus the go.mod in the working dir /mockgen is not considered.

In docker image the process runs under root and this first attempt to run prog.go in module cache directory succeeds.

Without docker the first attempt to run prog.go fails (because of lack of permissions on the module cache directory) and the second attempt runs prog.go in the working dir /mockgen (this piece of code https://github.com/golang/mock/blob/master/mockgen/reflect.go#L164). That second attempt correctly resolves your required version of mockgen_test in go.mod

@minicuts
Copy link
Contributor

minicuts commented Feb 3, 2020

@tocrafty can you now retest with the latest mockgen?

GO111MODULE=on go get github.com/golang/mock/mockgen@latest

@tocrafty
Copy link
Author

tocrafty commented Feb 6, 2020

@nguyenfilip Seem not work. mockgen v1.4.0 still tryies to pull the latest version, not th version required in go.mod.

@minicuts
Copy link
Contributor

minicuts commented Feb 6, 2020

@tocrafty Sorry I meant if you can try with master:

GO111MODULE=on go get github.com/golang/mock/mockgen@master

@tocrafty
Copy link
Author

tocrafty commented Feb 6, 2020

It worked. Thanks.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants