Search code examples
gogo-modules

Find the Pseudo-version of the current, main module


I have a Go codegen tool and while building it as a binary I want to inject it's own current Pseudo-version for it's main module at build time using Go the tools.

I know that for dependencies, I can find their pseudo-version using go list -m all or go list -m -f '{{ .Version }}' $MODULE. The version for the main module is listed as empty.

I know that I can probably calculate the current pseudo version with:

git describe --tags `git rev-list --tags --max-count=1`

and:

TZ=UTC git --no-pager show \
   --quiet \
   --abbrev=12 \
   --date='format-local:%Y%m%d%H%M%S' \
   --format="%cd-%h"

To get a reasonable approximation like: v0.3.0-20210907161133-495c072cb418

After I have the Pseudo-version, I intend to inject it at build time like this:

go build -ldflags="-X generate.version v0.3.0-20210907161133-495c072cb418" -o mytool ./main.go

However, the recommendation is to use a Go tool directly to get the current Pseudo-version rather than some hacky bash thing I worked out on a napkin. Any suggestions as to how to do this?


Solution

  • The thing with pseudo-versions is that it's just an encoding for a particular revision in a VCS (not just Git).

    And, it is typically used when a module has no semver tag, or when you require just that, a particular revision, which can be a branch name.

    Pseudo-versions may refer to revisions for which no semantic version tags are available. They may be used to test commits before creating version tags, for example, on a development branch.

    So to have a pseudo-version, to begin with you must refer to a revision. Now, which one is the revision that most accurately describes your project, it will be up to you. The tip of the master branch might good enough, therefore:

    go list -f '{{.Version}}' -m example.com/mymodule@master
    

    Notice the syntax module@version, which allows you to choose a specific revision, hence, get the corresponding pseudo-version.