petergtz/pegomock

Master incompatible with versioned release

bagmangood opened this issue ยท 21 comments

When attempting to use pegomock in CI, we're pulling pegomock using go get github.com/petergtz/pegomock/... and then generating our mocks with go generate.

However, the latest commits to master are incompatible with the 1.0.0 release from yesterday. Attempting to use them results in:

undefined: pegomock.Option when running tests.

I'd suggest either minting a new release (1.1.0) as a possible option for those of us who can't lock our go get versions

^ Same issue here. If we were able to pull a specific version of the tool / generator using go get github.com/petergtz/pegomock@v1.0.0 it would solve this issue. But teams not upgraded to modules cannot do this, and go get pulls the latest master, which is incompatible with v1.0.0.

Hey @bagmangood & @jpopadak,

Sorry about this. I'm still figuring how to best do versioning. My original thought was that I could simply treat master as "experimental" and that you should track something like 1.x with the promise that this will not break. And then, once I'm happy with the state of master, release a new major version whenever I know there is breaking change.

Before changing my strategy, let me try to better understand your issue.

undefined: pegomock.Option when running tests.

Does this happen even after regenerating new mocks? If so, that would be unexpected. Would you mind providing more of the error stack trace you get?

Any ideas how to improve the experience? I'd like to be able to introduce changes that require regenerating the mocks and I'd like to mark these with major version bumps. But even if I do this, those will end up on master and go get will simply get the latest.

So I am using dep, and since you had no specific version before, dep was tracking master. But then dep today saw the new version, and decided to pull that instead since its a release and not a developer master branch. But even then, if we tracked v1.0.0 in dep, the generator tool is always based upon master with how go get works (you can never pick a specific version unless you're in a go modules project).

Outside of this behavior, I dont know a great way to do this. And this is something the Go Community has been debating for a very long time. Here is the recommended way if using modules, but it is a goofy way to do it: https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module

FWIW the only (not very great) solution I can think of is when breaking changes (like pegomock.Option) are merged, then a patch version is released. While not ideal, it doesn't seem like the existing tooling has a healthier solution for it.

I think your goals with the release are 100% spot on and an ideal state for packaging, I just don't think dep and the other package managers support it (yet?)

One thing I can think of (which people might not be a fan of) is separating out the library repo vs the tooling / generator repo. This would allow you to independently update the library and the tooling without one arguing with the other on breaking changes.

To give you more info on the undefined: pegomock.Option error, it doesnt give us anything else besides that when running go test after I regenerate the mocks:

# github.com/project/internal/app/module/mock_rg
internal/app/module/mock_rg/mock_repository.go:19:35: undefined: pegomock.Option

Or there's always trunk (experimental) vs. master (stable)

Example of a mature pattern around that: ruby

Hey guys,

Thanks, this helps quite a bit. I think I understand the issue now. I didn't realize that the generate tool is the problem because it's always on master. I always thought I'd have to make sure old mocks are not broken unless a new major version is introduced.

I must say I didn't jump on the modules band-wagon yet, because I wanted to wait until it's more mature. So https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module definitely seems like a solution, but I will need more time to implement this.

Also, @jpopadak, yes, I have also been thinking about separating out the library, but am somehow not convinced yet. I'd be worried that it raises the barrier to using Pegomock the first time.

So to unblock you guys as quickly as possible, I'm wondering if I should simply release a version 2.0.0 that you guys can consume. That way, your library and generate tool are in sync again. You might have to change the version you are tracking, but that sounds doable. Would that work for you?

And yes, @bagmangood, I think I will introduce a development branch somehow, so we don't get into this ugly unsynced mode between library and tool. Thanks to both of you!

Sounds good to me on the new version and dev branch ideas.

I dont think the go modules will solve this issue. Just by reading what they have been discussing, it seems like the go modules team doesnt want to do this, but most of the community does. Its an ongoing battle between the two.

minting a new release would definitely solve my problems, thanks!

Done. Pegomock 2.0.0 is out.

I dont think the go modules will solve this issue. Just by reading what they have been discussing, it seems like the go modules team doesnt want to do this, but most of the community does. Its an ongoing battle between the two.

OK, I definitely need to follow up on this.

Thanks again for your help guys! I'm closing this now. Please re-open if you find other problems.

@petergtz One thing to note, when you create these versions / tags, they should be in the format v2.0.0 with a v in the front. Doing so will allow Go Modules / vgo to properly find the correct version. If you have a Go Modules project and you attempt to pull in go get github.com/petergtz/pegomock@2.0.0 it fails saying it cant find it. If the tag you created was @v2.0.0, go get would find the proper version and as a result, the vgo / go build would find the v2.0.0 tag.

@jpopadak I'd just add an additional tag v2.0.0 to current master (which also has the 2.0.0 tag) and let the latest release point to that. Do you think that will fix your issue?

/cc @bagmangood

I am not working in any projects that have go modules enabled at the moment so I can't verify, I'm only using dep at the moment (which appeared to work without the v)

@jpopadak Added the tag. Let me know if that works for you. Thanks.

Hi @petergtz,

I ran into the same problem today. I am working with go modules, although I also think, that the core problem is that the pegomock command can't be vendored. (I've run into the same issue in the past, before using go modules.)

So https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module definitely seems like a solution, but I will need more time to implement this.

I tried this solution, but didn't get it to work:

// #build ignore

package lib

import (
	"os"

	"github.com/petergtz/pegomock/pegomock"
)

func main() {
	pegomock.Run(os.Args, os.Stderr, os.Stdin, app, make(chan bool))
}

With this I get the following error: import "github.com/petergtz/pegomock/pegomock" is a program, not an importable package

Another possible solution would be to add binary artifacts for the pegomock command to the releases. This would enable downloading a specific version of the tool.

@relnod FYI if you are using go modules, you can do a go get to the specific version, doesn't solve it if you need multiple versions in multiple projects but can solve for CI/isolated projects

I believe the syntax is go get github.com/petergtz/pegomock/...@v1.0.0 for the 1.0 release for example

Hey @relnod,

Hopefully, @bagmangood's suggestion helped you (or will help you).

Still, I like the idea of providing it as binary artifact, now that I am providing releases already. I would probably support the usual suspects (Linux, MacOS, and Windows, all 64bit only). Will see if I can implement that sometime soon.

Thanks!

@petergtz @bagmangood Unfortunatelly I didn't get it to work with
go get github.com/petergtz/pegomock/...@v2.0.0

I guess I'm just going to wait for the binary releases.

Maybe goreleaser can help with releasing the binaries? I have never tried it myself though.

@relnod Just added binaries to release v2.0.1 using goreleaser.

It looks like I forgot to close this issue. Closing now. Feel free to re-open in case I'm missing something.