databricks-cli/internal/build/info.go

120 lines
2.4 KiB
Go

package build
import (
"fmt"
"runtime/debug"
"strconv"
"sync"
"time"
"golang.org/x/mod/semver"
)
type Info struct {
ProjectName string
Version string
Branch string
Tag string
ShortCommit string
FullCommit string
CommitTime time.Time
Summary string
Major int64
Minor int64
Patch int64
Prerelease string
IsSnapshot bool
BuildTime time.Time
}
var info Info
var once sync.Once
const DefaultSemver = "0.0.0-dev"
// getDefaultBuildVersion uses build information stored by Go itself
// to synthesize a build version if one wasn't set.
// This is necessary if the binary was not built through goreleaser.
func getDefaultBuildVersion() string {
bi, ok := debug.ReadBuildInfo()
if !ok {
panic("unable to read build info")
}
m := make(map[string]string)
for _, s := range bi.Settings {
m[s.Key] = s.Value
}
out := DefaultSemver
// Append revision as build metadata.
if v, ok := m["vcs.revision"]; ok {
// First 12 characters of the commit SHA is plenty to identify one.
out = fmt.Sprintf("%s+%s", out, v[0:12])
}
return out
}
func initialize() {
// If buildVersion is empty it means the binary was NOT built through goreleaser.
// We try to pull version information from debug.BuildInfo().
if buildVersion == "" {
buildVersion = getDefaultBuildVersion()
}
// Confirm that buildVersion is valid semver.
// Note that the semver package requires a leading 'v'.
if !semver.IsValid("v" + buildVersion) {
panic(fmt.Sprintf(`version is not a valid semver string: "%s"`, buildVersion))
}
info = Info{
ProjectName: buildProjectName,
Version: buildVersion,
Branch: buildBranch,
Tag: buildTag,
ShortCommit: buildShortCommit,
FullCommit: buildFullCommit,
CommitTime: parseTime(buildCommitTimestamp),
Summary: buildSummary,
Major: parseInt(buildMajor),
Minor: parseInt(buildMinor),
Patch: parseInt(buildPatch),
Prerelease: buildPrerelease,
IsSnapshot: parseBool(buildIsSnapshot),
BuildTime: parseTime(buildTimestamp),
}
}
func GetInfo() Info {
once.Do(initialize)
return info
}
func parseInt(s string) int64 {
i, err := strconv.ParseInt(s, 10, 64)
if err != nil {
panic(err)
}
return i
}
func parseBool(s string) bool {
b, err := strconv.ParseBool(s)
if err != nil {
panic(err)
}
return b
}
func parseTime(s string) time.Time {
return time.Unix(parseInt(s), 0)
}