mirror of
https://github.com/Cheviiot/Vintner.git
synced 2026-08-03 15:57:24 +00:00
Show git commit and build time in vintner version
Uses Go's automatic VCS build-info stamping (vcs.revision/vcs.time/ vcs.modified, embedded by `go build` since Go 1.18 - no -ldflags changes needed, works the same for a CI release build and a plain local `go build`). Knowing the exact commit a bug report's binary was built from, not just the X.Y.Z tag, is the point - two builds of the same tag could still differ. Split the pure formatting logic (formatVersion) from the debug.ReadBuildInfo() call so it's actually unit-testable: `go test` binaries don't get VCS stamping the way `go build` ones do, so there was no way to exercise the revision-formatting branch through versionString() itself.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
// versionString renders "vintner <version>" plus, when available, the git
|
||||
// commit and build time Go's toolchain embeds automatically (since Go
|
||||
// 1.18, `go build` stamps vcs.revision/vcs.time/vcs.modified into the
|
||||
// binary on its own - no -ldflags needed for this part, so it works the
|
||||
// same whether the binary came from CI or a plain local `go build`).
|
||||
// Knowing the exact commit a reported bug was built from, not just the
|
||||
// X.Y.Z tag, is the point: two builds of the same tag could still differ
|
||||
// if the tag was ever moved, or if someone built from an uncommitted tree.
|
||||
//
|
||||
// Note for anyone testing this: `go build` stamps vcs.* build settings,
|
||||
// but `go test` binaries don't get them - there's no environment where a
|
||||
// `go test` run can exercise the revision-formatting branch below, hence
|
||||
// formatVersion is split out and tested directly instead.
|
||||
func versionString() string {
|
||||
revision, buildTime, dirty := "", "", false
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
for _, s := range info.Settings {
|
||||
switch s.Key {
|
||||
case "vcs.revision":
|
||||
revision = s.Value
|
||||
case "vcs.time":
|
||||
buildTime = s.Value
|
||||
case "vcs.modified":
|
||||
dirty = s.Value == "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
return formatVersion(version, revision, buildTime, dirty)
|
||||
}
|
||||
|
||||
// formatVersion is the pure part of versionString: given a revision (full
|
||||
// git SHA, may be empty), it's shortened to 12 chars and marked "-dirty" if
|
||||
// the build tree had uncommitted changes.
|
||||
func formatVersion(ver, revision, buildTime string, dirty bool) string {
|
||||
v := "vintner " + ver
|
||||
if revision == "" {
|
||||
return v
|
||||
}
|
||||
if len(revision) > 12 {
|
||||
revision = revision[:12]
|
||||
}
|
||||
if dirty {
|
||||
revision += "-dirty"
|
||||
}
|
||||
if buildTime != "" {
|
||||
return fmt.Sprintf("%s (%s, %s)", v, revision, buildTime)
|
||||
}
|
||||
return fmt.Sprintf("%s (%s)", v, revision)
|
||||
}
|
||||
Reference in New Issue
Block a user