Closed sugarjig closed 6 years ago
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.
@sugarjig https://github.com/golang/mock/pull/28 was merged and I believe that fixes your issue here.
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.
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.
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) ...
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.
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 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.
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 withgomock
for the same reason. We usegovendor
for this.We vendorize
gomock
withgovendor fetch github.com/golang/mock/mockgen@v1.0.0
. Then, we can installmockgen
from thevendor/
directory usinggovendor install +vendor
. However, when we try to runmockgen
, we get the following output:This is obviously because the package
github.com/golang/mock/mockgen/model
is not at the mentioned locations, but under ourvendor/
directory. One way to fix this is to rungo get -u github.com/golang/mock/mockgen
, which places themodel
package under$GOPATH
. Another way is to rungovendor 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 themockgen
binary? Is there any way to installmockgen
from the vendor directory?