golang / mock

GoMock is a mocking framework for the Go programming language.
Apache License 2.0
9.31k stars 609 forks source link

Support --version flag or similar option in mockgen #250

Closed a1gemmel closed 4 years ago

a1gemmel commented 5 years ago

It would be nice to be able to know what version of mockgen I have installed via a flag or command, like:

mockgen -v mockgen -version mockgen --version mockgen version

Any of the above, really.

poy commented 5 years ago

This is a great idea. The only hard part is how to supply the version. I think most developers pull mockgen via go get, and not from a github release. Therefore we can't necessarily use compile flags or something like that to supply the version to the binary. This implies we have to have a constant in the code capturing the current version (which is a little weird).

I think if we want to supply this, then we need to start publishing this stuff to github and encourage people to get it from there.

@balshetzer Do you have any thoughts?

Rossiar commented 4 years ago

@codyoss @poy any plans to work on this soon? I've just spent half a day debugging a -self_package issue and it was all because I was pulling master and not the latest release (1.3.1)

Right now on master the README.md tells users to run:

go get github.com/golang/mock/mockgen
go install github.com/golang/mock/mockgen

These commands will just install the latest code from master - which right now seems to come with a bunch of unwanted side-effects (as I've found out today).

I think using compile flags and uploading the binaries with the release is a really good approach going forward - adding the --version option as well I think will clear up a lot of confusion when reporting issues - our team really loves using gomock so I'd be happy to offer some of our time to implement this feature (with your guidance).

minicuts commented 4 years ago

@Rossiar I can look a bit more into this. @codyoss let me know in case you already have some ideas how to implement this. Otherwise I will do some research so that both go get and direct binary usage works reasonably.

codyoss commented 4 years ago

I know some libraries just have a constant string that gets exposed. We could write a release script that automatically bumps it, etc. I have no strong opinions.

minicuts commented 4 years ago

My suggestion of how to address this is in #362 . Since most of the people use go get I think we can continue supporting that workflow. Version information is available if module aware mode is used. In GOPATH mode I suggest we print a warning message for the users informing them they are running some random version of the binary.

I think exposed constant string is a little bit of a hassle. Lets say we bump the constant string to v1.4.0 in commit X and then over the course of a few days we add a few more commits. Anybody who runs go get since X will see gomock -version to output v1.4.0, regardless of the commits added on top of X.

BradErz commented 4 years ago

to be perfectly honest the way we implement this for our services is

Makefile

VERSION ?= $(shell git rev-parse --short HEAD)

LDFLAGS = -ldflags "-X main.version=$(VERSION) -X main.appName=$(APP_NAME)"

.PHONY: build
build: ## Build the binary
    @echo "Building binary"
    $(GOENV) go build $(LDFLAGS) -a -installsuffix cgo \
    -o $(APP_NAME) ./cmd/$(APP_NAME)

cmd/app/main.go

var (
    appName     = "ext-auth"
    version     = "1.0.0"
)

So by default its the commit message, and any release is the semantic version. But this only works for built artifacts, i guess it wont work with a go get install :cry:

minicuts commented 4 years ago

@BradErz yeah. there are basically 3 ways to implement this:

  1. build flags
  2. constant string in code
  3. exposing module metadata

In #362 I am leaning to exposing the module metadata. For the exact reason you mentioned - we do not distribute binary itself.

Rossiar commented 4 years ago

If this solution works as you say in #362:

As soon as we release 1.3.2, the -version flag should report v1.3.2 if go get is invoked with @latest. I think there is no way to test this with mockgen itself now. But I tested the debug.ReadBuildInfo in my other test project.

One edge case is when somebody invokes the go get with @master. But it does behave correctly. With @master the resulting version should be something like: v1.3.2-0.20191220092011-827cab0badc9, in other words if the go get is requsted to download an unreleased version, the module support adds commit SHA to the version string to disambiguate the version.

There are multiple situations when -version is not going to be available (but I think that is fine):

  • when building/running the mockgen module locally the -version is (devel)
  • when running with Golang older then 1.12 (as seen in the changes in this PR)

And I can run

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

and it will install the latest released version into my $GOPATH/bin and not the HEAD of master then I am happy.

Can you clarify that this is the behaviour once v1.3.2 is released?

minicuts commented 4 years ago

@Rossiar thanks for checking in. Yes that is the behavior I want to introduce. If you will run the command

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

You will be (after v1.3.2) able to use -version to verify the version.

Rossiar commented 4 years ago
➜  ~ GO111MODULE=on go get github.com/golang/mock/mockgen@latest
go: finding github.com/golang/mock v1.4.0
go: downloading github.com/golang/mock v1.4.0
go: extracting github.com/golang/mock v1.4.0
➜  ~ mockgen -version
v1.4.0
➜  ~ 

LGTM - @codyoss I think this can be closed