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

Cannot install and run mockgen from the vendor directory #95

Closed
sugarjig opened this issue Jul 24, 2017 · 9 comments
Closed

Cannot install and run mockgen from the vendor directory #95

sugarjig opened this issue Jul 24, 2017 · 9 comments

Comments

@sugarjig
Copy link

We would like to "vendorize" mockgen in our project, in order to freeze the version we are using and prevent unexpected breakages. We already do this with gomock for the same reason. We use govendor for this.

We vendorize gomock with govendor fetch github.com/golang/mock/mockgen@v1.0.0. Then, we can install mockgen from the vendor/ directory using govendor install +vendor. However, when we try to run mockgen, we get the following output:

prog.go:11:2: cannot find package "github.com/golang/mock/mockgen/model" in any of:
        /usr/local/Cellar/go/1.8.3/libexec/src/github.com/golang/mock/mockgen/model (from $GOROOT)
        /<omitted>/go/src/github.com/golang/mock/mockgen/model (from $GOPATH)

This is obviously because the package github.com/golang/mock/mockgen/model is not at the mentioned locations, but under our vendor/ directory. One way to fix this is to run go get -u github.com/golang/mock/mockgen, which places the model package under $GOPATH. Another way is to run govendor get -u github.com/golang/mock/mockgen@v1.0.0, which is what we currently do. The advantage to "vendorizing" it as described above is that it centralizes the version management with the rest of our dependencies.

Why is there a runtime dependency on this model package? Shouldn't it be compiled into the mockgen binary? Is there any way to install mockgen from the vendor directory?

@kaedys
Copy link

kaedys commented Oct 11, 2017

Worth noting, why it has a runtime dependency (which isn't normally a thing for Go programs) is because mockgen actually creates a new program, using the built in template package, then compiles and runs it to generate the mock. It does this so it can actually import the package being mocked directly, allowing it to use the reflection package to get information about the types instead of having to parse the file (which runs into problems if the package being mocked imports and uses types from other packages). Reference: https://github.com/golang/mock/blob/master/mockgen/reflect.go#L118

It uses the mock/model package in this template function to access a number of helper functions that it uses to parse the reflection return. In theory, these functions could instead be written directly into the generated program, removing the dependency, but then the authors would lose the ability to compile-time verify that code and go test it.

Not sure if there's a clean and elegant solution to your use case, unfortunately.

@mandazi
Copy link

mandazi commented Feb 13, 2018

@sugarjig #28 was merged and I believe that fixes your issue here.

@sugarjig
Copy link
Author

It looks like that PR was to add support for mocking vendored dependencies, whereas what we're looking for is "vendorizing" gomock. The idea is to pin gomock to a specific version. Using govendor get -u github.com/golang/mock/mockgen@v1.0.0 is currently working for us, though.

@blind-oracle
Copy link

Use https://github.com/twitchtv/retool

@kaedys
Copy link

kaedys commented Mar 1, 2018

A useful tool, @blind-oracle, but I don't think it will actually solve the problem, at least on its own. The issue here is that mockgen has a runtime dependency on one of its source files, so the only way to make it work with vendoring is to build the template reflection program inside the source tree that vendors gomock. This will require a change to the mockgen code itself, probably by allowing the user to specify a build location.

@LasTshaMAN
Copy link

LasTshaMAN commented Mar 17, 2018

Any updates on this issue ?

The thing is, when a project relies on "vendor" directory (which, I believe, most of them do) it can't use reflect mode for mockgen ...

And reflect mode is the recommended one, because in source mode you can't even mock embedded interface like io.Writer (as far as I know) ...

@kaedys
Copy link

kaedys commented Mar 20, 2018

The thing is, when a project relies on "vendor" directory (which, I believe, most of them do) it can't use reflect mode for mockgen ...

It can, actually, as of #28 and #99. The only thing that isn't currently possible (and what this ticket is about) is vendoring gomock itself and then using the vendored version to generate your mock code.

@sugarjig
Copy link
Author

sugarjig commented Apr 4, 2018

On the suggestion of @blind-oracle I gave retool a try, and it is working for us. We are able to check in a specific version of mockgen and use that by running retool do mockgen.

@sugarjig sugarjig closed this as completed Apr 4, 2018
@balshetzer
Copy link
Collaborator

@sugarjig I recently changed mockgen to try to run inside the code tree. I realize that this problem is solved for you with retool but if you're willing to try your original method again and report back then I'd appreciate it.

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

No branches or pull requests

6 participants