Fossil Forum
Post: TIL: Go embeds Fossil version info into binaries
The new fossil whatis -h flag is most welcome and will doubtless replace many local hand-rolled alternatives. However, if you're using Go, you don't need to call fossil manually at all. Given this main.go:
package main
import (
"flag"
"fmt"
"os"
"runtime/debug"
)
var Version string
func getVCSInfo() string {
if info, ok := debug.ReadBuildInfo(); ok {
for _, s := range info.Settings {
if s.Key == "vcs.revision" {
rev := s.Value
if len(rev) >= 10 {
return "[" + rev[:10] + "]"
}
return "[" + rev + "]"
}
}
}
return "UNKNOWN"
}
func main() {
showVersion := flag.Bool("version", false, "show version and exit")
flag.Parse()
if *showVersion {
if Version != "" {
fmt.Println(Version)
} else {
fmt.Println(getVCSInfo())
}
os.Exit(0)
}
fmt.Println("go-fsl-version demo")
}
…and this go.mod:
module go-fsl-version
go 1.21
…and this Makefile:
VERSION ?= 0.1.0
build:
go build -o go-fsl-version .
release:
go build -ldflags "-X main.Version=$(VERSION)" -o go-fsl-version .
.PHONY: build release
…you can now pull off stunts like these:
$ make && ./go-fsl-version -version
UNKNOWN
$ fossil init ../go-fsl-version.fossil
$ fossil open -f ../go-fsl-version.fossil
$ make && ./go-fsl-version -version
[6927174644]
$ make release && ./go-fsl-version -version
0.1.0
$ VERSION=0.2.0-beta1 make release && ./go-fsl-version -version
0.2.0-beta1
Now your release builds are tagged with the VERSION from the Makefile — which can be manually overridden as we see in the last command — but pre-release builds are tagged with a 10-digit prefix of the commit that produced them.
Z ebc4eb6
Yeah, it's available since Go 1.18.
And the tooling learned to go get Fossil-hosted repos in 1.10.
To be honest, both times I was pleasantly surprised. Even though here at my $dayjob we're obviously using Git to host Go code, this level of support gives me that warm cozy feeling ;-)