rely on `go build` stamping a version for local builds

Before Go 1.24, `go build` only stamped module versions for modules
resolved via GOPROXY, as the local module only had VCS information.
For that reason, we manually built a pseudo-version from the VCS
timestamp and revision stamped for local builds.

Go 1.24 started stamping the main module with a module version
derived from the local VCS information, much like we already did.
For example, comparing a clean build before this change
against a build with this uncommitted change:

    $ go install
    $ garble version
    mvdan.cc/garble v0.14.3-0.20250413182748-e97968ccae46
    [...]
    $ git stash pop
    $ go install
    $ garble version
    mvdan.cc/garble v0.14.3-0.20250413182748-e97968ccae46+dirty
    [...]

The only user-visible change is that local builds with any
uncommitted changes now get a `+dirty` suffix, but that's probably
a good thing for the majority of users, and provides a useful hint
in case a user forgot about local changes.

The test logic to inject VCS information via an env var
and see that the resulting pseudo-version is what we expect can go too,
as that was testing our own main module version logic.
We now rely on `go build` to do the right thing, so don't test that.
pull/940/head
Daniel Martí 1 week ago
parent d72d89aaf0
commit 87a8360d61
No known key found for this signature in database

@ -42,7 +42,6 @@ import (
"unicode/utf8"
"github.com/rogpeppe/go-internal/cache"
"golang.org/x/mod/module"
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/go/ssa"
"mvdan.cc/garble/internal/ctrlflow"
@ -371,38 +370,6 @@ func mainErr(args []string) error {
mod = mod.Replace
}
// For the tests.
if v := os.Getenv("GARBLE_TEST_BUILDSETTINGS"); v != "" {
var extra []debug.BuildSetting
if err := json.Unmarshal([]byte(v), &extra); err != nil {
return err
}
info.Settings = append(info.Settings, extra...)
}
// Until https://github.com/golang/go/issues/50603 is implemented,
// manually construct something like a pseudo-version.
// TODO: remove when this code is dead, hopefully in Go 1.22.
if mod.Version == "(devel)" {
var vcsTime time.Time
var vcsRevision string
for _, setting := range info.Settings {
switch setting.Key {
case "vcs.time":
// If the format is invalid, we'll print a zero timestamp.
vcsTime, _ = time.Parse(time.RFC3339Nano, setting.Value)
case "vcs.revision":
vcsRevision = setting.Value
if len(vcsRevision) > 12 {
vcsRevision = vcsRevision[:12]
}
}
}
if vcsRevision != "" {
mod.Version = module.PseudoVersion("", "", vcsTime, vcsRevision)
}
}
fmt.Printf("%s %s\n\n", mod.Path, mod.Version)
fmt.Printf("Build settings:\n")
for _, setting := range info.Settings {

@ -87,26 +87,12 @@ stderr 'directory not found'
# Test the version command. Note that test binaries exclude VCS build info,
# and we reuse the test binary for garble itself, so that's missing.
# To avoid building another garble binary,
# and to be able to use static VCS info, use an environment variable.
# First, test without the information, and then with it.
exec garble version
stdout -count=1 'mvdan.cc/garble \(devel\)'
stdout -count=1 'Build settings'
stdout -count=3 '-compiler|GOOS|GOARCH'
! stdout 'vcs'
# Obtained from a real build while developing.
env GARBLE_TEST_BUILDSETTINGS='[{"Key":"vcs","Value":"git"},{"Key":"vcs.revision","Value":"91ea246349544769f5100c29f79cb0f173abfeea"},{"Key":"vcs.time","Value":"2022-03-18T13:45:11Z"},{"Key":"vcs.modified","Value":"true"}]'
exec garble version
stdout -count=1 'mvdan\.cc/garble v0\.0\.0-20220318134511-91ea24634954'
stdout -count=1 'Build settings'
stdout -count=3 '-compiler|GOOS|GOARCH'
stdout -count=1 'vcs git'
stdout -count=1 'vcs\.revision 91ea246349544769f5100c29f79cb0f173abfeea'
stdout -count=1 'vcs\.time 2022-03-18T13:45:11Z'
stdout -count=1 'vcs\.modified true'
! exec garble version -flag
stderr 'usage: garble version'

Loading…
Cancel
Save