Skip to content

Commit

Permalink
make "garble version" include VCS information
Browse files Browse the repository at this point in the history
When someone builds garble from a git clone,
the resulting binary used to not contain any information:

	$ garble version
	(devel)

Since Go 1.18, VCS information is stamped by default into binaries.
We now print it, alongside any other available build settings:

	$ garble version
	mvdan.cc/garble (devel)

	Build settings:
	       -compiler gc
	     CGO_ENABLED 1
	          GOARCH amd64
	            GOOS linux
	         GOAMD64 v3
	             vcs git
	    vcs.revision 91ea246
	        vcs.time 2022-03-18T13:45:11Z
	    vcs.modified true

Note that it's still possible for a garble build to contain no useful
version information, such as when built via "go build -buildvcs=false".
However, if a user opts into omitting the information, it's on them to
figure out what version of garble they actually built.

While here, bump test-gotip.

Fixes #491.
  • Loading branch information
mvdan authored and lu4p committed Mar 26, 2022
1 parent 1c564ef commit 6a39ad2
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Expand Up @@ -72,7 +72,7 @@ jobs:
steps:
- name: Install Go
env:
GO_COMMIT: e475cf2e705d4eda8647426e060898ab3f643610 # 2022-03-14
GO_COMMIT: 80a7504a13a5dccb60757d1fc66d71bcba359799 # 2022-03-25
run: |
cd $HOME
mkdir $HOME/gotip
Expand Down
52 changes: 40 additions & 12 deletions main.go
Expand Up @@ -42,11 +42,7 @@ import (
"mvdan.cc/garble/internal/literals"
)

var (
flagSet = flag.NewFlagSet("garble", flag.ContinueOnError)

version = "(devel)" // to match the default from runtime/debug
)
var flagSet = flag.NewFlagSet("garble", flag.ContinueOnError)

var (
flagLiterals bool
Expand Down Expand Up @@ -328,15 +324,47 @@ func mainErr(args []string) error {
fmt.Fprintf(os.Stderr, "usage: garble version\n")
return errJustExit(2)
}
// don't overwrite the version if it was set by -ldflags=-X
if info, ok := debug.ReadBuildInfo(); ok && version == "(devel)" {
mod := &info.Main
if mod.Replace != nil {
mod = mod.Replace
info, ok := debug.ReadBuildInfo()
if !ok {
// The build binary was stripped of build info?
// Could be the case if garble built itself.
fmt.Println("unknown")
return nil
}
mod := &info.Main
if mod.Replace != nil {
mod = mod.Replace
}

// For the tests.
if v := os.Getenv("GARBLE_TEST_VERSION"); v != "" {
mod.Version = v
}
if v := os.Getenv("GARBLE_TEST_SUM"); v != "" {
mod.Sum = v
}
if v := os.Getenv("GARBLE_TEST_SETTINGS"); v != "" {
var extra []debug.BuildSetting
if err := json.Unmarshal([]byte(v), &extra); err != nil {
return err
}
info.Settings = append(info.Settings, extra...)
}

fmt.Printf("%s %s %s\n\n", mod.Path, mod.Version, mod.Sum)
fmt.Printf("Build settings:\n")
for _, setting := range info.Settings {
if setting.Value == "" {
continue // do empty build settings even matter?
}
version = mod.Version
// The padding helps keep readability by aligning:
//
// veryverylong.key value
// short.key some-other-value
//
// Empirically, 16 is enough; the longest key seen is "vcs.revision".
fmt.Printf("%16s %s\n", setting.Key, setting.Value)
}
fmt.Println(version)
return nil
case "reverse":
return commandReverse(args)
Expand Down
26 changes: 25 additions & 1 deletion testdata/scripts/help.txt
Expand Up @@ -77,8 +77,32 @@ stderr 'must precede command, like: garble -seed=random build \./pkg'
[windows] ! garble C:\does\not\exist\compile
stderr 'not running "garble \[command\]"'

# 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.
#
# Note that Go 1.18.0 shipped with -buildvcs=true for "go test",
# so it's a special case that we need to handle until 1.18.1 is out.
garble version
stdout 'devel|^v0'
stdout -count=1 'mvdan.cc/garble \(devel\)'
stdout -count=1 'Build settings'
stdout -count=3 '-compiler|GOOS|GOARCH'
[go1.19] ! stdout 'vcs'

env GARBLE_TEST_VERSION='v0.88.99'
env GARBLE_TEST_SUM='h1:someBase64epYSXwA'
# Obtained from a real build while developing.
env GARBLE_TEST_SETTINGS='[{"Key":"vcs","Value":"git"},{"Key":"vcs.revision","Value":"91ea246349544769f5100c29f79cb0f173abfeea"},{"Key":"vcs.time","Value":"2022-03-18T13:45:11Z"},{"Key":"vcs.modified","Value":"true"}]'
garble version
stdout -count=1 'mvdan.cc/garble v0\.88\.99 h1:someBase64epYSXwA'
stdout -count=1 'Build settings'
stdout -count=3 '-compiler|GOOS|GOARCH'
[go1.19] stdout -count=1 'vcs git'
[go1.19] stdout -count=1 'vcs.revision 91ea246349544769f5100c29f79cb0f173abfeea'
[go1.19] stdout -count=1 'vcs.time 2022-03-18T13:45:11Z'
[go1.19] stdout -count=1 'vcs.modified true'

! garble version -flag
stderr 'usage: garble version'
Expand Down

0 comments on commit 6a39ad2

Please sign in to comment.