Skip to content

Commit

Permalink
Merge pull request #226 from safing/migrate-build-info
Browse files Browse the repository at this point in the history
Migrate to runtime/debug.BuildInfo for most VCS information
  • Loading branch information
ppacher authored Mar 27, 2024
2 parents 704e9e2 + 045eedc commit a90357b
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 69 deletions.
115 changes: 58 additions & 57 deletions info/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,82 +5,89 @@ import (
"fmt"
"os"
"runtime"
"runtime/debug"
"strings"
"sync"
)

var (
name = "[NAME]"
version = "[version unknown]"
commit = "[commit unknown]"
license = "[license unknown]"
buildOptions = "[options unknown]"
buildUser = "[user unknown]"
buildHost = "[host unknown]"
buildDate = "[date unknown]"
buildSource = "[source unknown]"

compareVersion bool
name string
version = "dev build"
buildSource = "[source unknown]"
license = "[license unknown]"

info *Info
loadInfo sync.Once
)

// Info holds the programs meta information.
type Info struct {
Name string
Version string
License string
Commit string
BuildOptions string
BuildUser string
BuildHost string
BuildDate string
BuildSource string
Name string
Version string
License string
Commit string
Time string
Source string
Dirty bool

debug.BuildInfo
}

// Set sets meta information via the main routine. This should be the first thing your program calls.
func Set(setName string, setVersion string, setLicenseName string, compareVersionToTag bool) {
name = setName
version = setVersion
license = setLicenseName
compareVersion = compareVersionToTag
}

// GetInfo returns all the meta information about the program.
func GetInfo() *Info {
return &Info{
Name: name,
Version: version,
Commit: commit,
License: license,
BuildOptions: buildOptions,
BuildUser: buildUser,
BuildHost: buildHost,
BuildDate: buildDate,
BuildSource: buildSource,
}
loadInfo.Do(func() {
buildInfo, _ := debug.ReadBuildInfo()
buildSettings := make(map[string]string)
for _, setting := range buildInfo.Settings {
buildSettings[setting.Key] = setting.Value
}

info = &Info{
Name: name,
Version: version,
License: license,
BuildInfo: *buildInfo,
Source: buildSource,
Commit: buildSettings["vcs.revision"],
Time: buildSettings["vcs.time"],
Dirty: buildSettings["vcs.modified"] == "true",
}
})

return info
}

// Version returns the short version string.
func Version() string {
if !compareVersion || strings.HasPrefix(commit, fmt.Sprintf("tags/v%s-0-", version)) {
return version
info := GetInfo()

if info.Dirty {
return version + "*"
}
return version + "*"

return version
}

// FullVersion returns the full and detailed version string.
func FullVersion() string {
s := ""
if !compareVersion || strings.HasPrefix(commit, fmt.Sprintf("tags/v%s-0-", version)) {
s += fmt.Sprintf("%s\nversion %s\n", name, version)
} else {
s += fmt.Sprintf("%s\ndevelopment build, built on top version %s\n", name, version)
}
s += fmt.Sprintf("\ncommit %s\n", commit)
s += fmt.Sprintf("built with %s (%s) %s/%s\n", runtime.Version(), runtime.Compiler, runtime.GOOS, runtime.GOARCH)
s += fmt.Sprintf(" using options %s\n", strings.ReplaceAll(buildOptions, "§", " "))
s += fmt.Sprintf(" by %s@%s\n", buildUser, buildHost)
s += fmt.Sprintf(" on %s\n", buildDate)
s += fmt.Sprintf("\nLicensed under the %s license.\nThe source code is available here: %s", license, buildSource)
return s
info := GetInfo()

builder := new(strings.Builder)

builder.WriteString(fmt.Sprintf("%s\nversion %s\n", info.Name, Version()))
builder.WriteString(fmt.Sprintf("\ncommit %s\n", info.Commit))
builder.WriteString(fmt.Sprintf("built with %s (%s) %s/%s\n", runtime.Version(), runtime.Compiler, runtime.GOOS, runtime.GOARCH))
builder.WriteString(fmt.Sprintf(" on %s\n", info.Time))
builder.WriteString(fmt.Sprintf("\nLicensed under the %s license.\nThe source code is available here: %s", license, info.Source))

return builder.String()
}

// CheckVersion checks if the metadata is ok.
Expand All @@ -92,17 +99,11 @@ func CheckVersion() error {
return nil // testing on windows
default:
// check version information
if name == "[NAME]" {
if name == "[NAME]" || license == "[license unknown]" {
return errors.New("must call SetInfo() before calling CheckVersion()")
}
if version == "[version unknown]" ||
commit == "[commit unknown]" ||
license == "[license unknown]" ||
buildOptions == "[options unknown]" ||
buildUser == "[user unknown]" ||
buildHost == "[host unknown]" ||
buildDate == "[date unknown]" ||
buildSource == "[source unknown]" {

if version == "[version unknown]" {
return errors.New("please build using the supplied build script.\n$ ./build {main.go|...}")
}
}
Expand Down
21 changes: 9 additions & 12 deletions metrics/metrics_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@ func registerInfoMetric() error {
_, err := NewGauge(
"info",
map[string]string{
"version": checkUnknown(meta.Version),
"commit": checkUnknown(meta.Commit),
"build_options": checkUnknown(meta.BuildOptions),
"build_user": checkUnknown(meta.BuildUser),
"build_host": checkUnknown(meta.BuildHost),
"build_date": checkUnknown(meta.BuildDate),
"build_source": checkUnknown(meta.BuildSource),
"go_os": runtime.GOOS,
"go_arch": runtime.GOARCH,
"go_version": runtime.Version(),
"go_compiler": runtime.Compiler,
"comment": commentOption(),
"version": checkUnknown(meta.Version),
"commit": checkUnknown(meta.Commit),
"build_date": checkUnknown(meta.Time),
"build_source": checkUnknown(meta.Source),
"go_os": runtime.GOOS,
"go_arch": runtime.GOARCH,
"go_version": runtime.Version(),
"go_compiler": runtime.Compiler,
"comment": commentOption(),
},
func() float64 {
// Report as 0 the first time in order to detect (re)starts.
Expand Down

0 comments on commit a90357b

Please sign in to comment.