2020-08-06 20:58:47 +03:00
|
|
|
// Package buildinfo hosts build info variables populated via ldflags.
|
2023-04-19 08:28:09 +03:00
|
|
|
//
|
|
|
|
// For testing, you can override the build version
|
|
|
|
// using envar SQ_BUILD_VERSION (panics if not a valid semver).
|
2020-08-06 20:58:47 +03:00
|
|
|
package buildinfo
|
|
|
|
|
2022-12-30 20:10:56 +03:00
|
|
|
import (
|
|
|
|
"fmt"
|
2023-08-12 21:54:14 +03:00
|
|
|
"log/slog"
|
2023-04-19 08:28:09 +03:00
|
|
|
"os"
|
2022-12-30 20:10:56 +03:00
|
|
|
"strings"
|
2023-11-20 06:28:09 +03:00
|
|
|
"time"
|
2022-12-30 20:10:56 +03:00
|
|
|
|
2023-11-20 04:06:36 +03:00
|
|
|
"golang.org/x/mod/semver"
|
2023-05-07 05:36:34 +03:00
|
|
|
|
2023-04-02 22:49:45 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/lg/lga"
|
2023-11-20 04:06:36 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/timez"
|
2022-12-30 20:10:56 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// DefaultVersion is the default value for Version if not
|
2020-08-09 16:46:46 +03:00
|
|
|
// set via ldflags.
|
2022-12-30 20:10:56 +03:00
|
|
|
const DefaultVersion = "v0.0.0-dev"
|
2020-08-09 16:46:46 +03:00
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
var (
|
2020-08-09 16:46:46 +03:00
|
|
|
// Version is the build version. If not set at build time via
|
2022-12-30 20:10:56 +03:00
|
|
|
// ldflags, Version takes the value of DefaultVersion.
|
|
|
|
Version = DefaultVersion
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
// Commit is the commit hash.
|
|
|
|
Commit string
|
|
|
|
|
|
|
|
// Timestamp is the timestamp of when the cli was built.
|
|
|
|
Timestamp string
|
|
|
|
)
|
2022-12-30 20:10:56 +03:00
|
|
|
|
|
|
|
// BuildInfo encapsulates Version, Commit and Timestamp.
|
|
|
|
type BuildInfo struct {
|
2023-11-20 06:28:09 +03:00
|
|
|
Version string `json:"version" yaml:"version"`
|
|
|
|
Commit string `json:"commit,omitempty" yaml:"commit,omitempty"`
|
|
|
|
Timestamp time.Time `json:"timestamp,omitempty" yaml:"timestamp,omitempty"`
|
2022-12-30 20:10:56 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// String returns a string representation of BuildInfo.
|
|
|
|
func (bi BuildInfo) String() string {
|
|
|
|
s := bi.Version
|
|
|
|
if bi.Commit != "" {
|
|
|
|
s += " " + bi.Commit
|
|
|
|
}
|
2023-11-20 06:28:09 +03:00
|
|
|
if !bi.Timestamp.IsZero() {
|
|
|
|
s += " " + bi.Timestamp.Format(timez.RFC3339Z)
|
2022-12-30 20:10:56 +03:00
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2023-04-02 22:49:45 +03:00
|
|
|
// LogValue implements slog.LogValuer.
|
|
|
|
func (bi BuildInfo) LogValue() slog.Value {
|
|
|
|
gv := slog.GroupValue(
|
|
|
|
slog.String(lga.Version, bi.Version),
|
|
|
|
slog.String(lga.Commit, bi.Commit),
|
2023-11-20 06:28:09 +03:00
|
|
|
slog.Time(lga.Timestamp, bi.Timestamp))
|
2023-04-02 22:49:45 +03:00
|
|
|
|
|
|
|
return gv
|
|
|
|
}
|
|
|
|
|
2023-11-20 06:28:09 +03:00
|
|
|
// Get returns BuildInfo. If buildinfo.Timestamp cannot be parsed,
|
|
|
|
// the returned BuildInfo.Timestamp will be the zero value.
|
2023-06-21 15:28:15 +03:00
|
|
|
func Get() BuildInfo {
|
2023-11-20 06:28:09 +03:00
|
|
|
var t time.Time
|
|
|
|
if Timestamp != "" {
|
|
|
|
got, err := timez.ParseTimestampUTC(Timestamp)
|
|
|
|
if err == nil {
|
|
|
|
t = got
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-30 20:10:56 +03:00
|
|
|
return BuildInfo{
|
|
|
|
Version: Version,
|
|
|
|
Commit: Commit,
|
2023-11-20 06:28:09 +03:00
|
|
|
Timestamp: t,
|
2022-12-30 20:10:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() { //nolint:gochecknoinits
|
|
|
|
if strings.HasSuffix(Version, "~dev") {
|
|
|
|
Version = strings.Replace(Version, "~dev", "-dev", 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
if Version != "" && !semver.IsValid(Version) {
|
|
|
|
// We want to panic here because it is a pipeline/build failure
|
|
|
|
// to have an invalid non-empty Version.
|
2023-04-02 22:49:45 +03:00
|
|
|
panic(fmt.Sprintf("Invalid BuildInfo.Version value: %s", Version))
|
2022-12-30 20:10:56 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if Timestamp != "" {
|
|
|
|
// Make sure Timestamp is normalized
|
2023-05-07 05:36:34 +03:00
|
|
|
t := timez.TimestampToRFC3339(Timestamp)
|
2022-12-30 20:10:56 +03:00
|
|
|
if t != "" {
|
|
|
|
Timestamp = t
|
|
|
|
}
|
|
|
|
}
|
2023-04-19 08:28:09 +03:00
|
|
|
|
|
|
|
if v, ok := os.LookupEnv(EnvOverrideVersion); ok {
|
|
|
|
if !semver.IsValid(v) {
|
|
|
|
panic(fmt.Sprintf("Invalid semver value from %s: %s", EnvOverrideVersion, v))
|
|
|
|
}
|
|
|
|
|
|
|
|
Version = v
|
|
|
|
}
|
2022-12-30 20:10:56 +03:00
|
|
|
}
|
|
|
|
|
2023-04-19 08:28:09 +03:00
|
|
|
// EnvOverrideVersion is used for testing build version, e.g. for
|
|
|
|
// config upgrades.
|
|
|
|
const EnvOverrideVersion = `SQ_BUILD_VERSION`
|
|
|
|
|
2022-12-30 20:10:56 +03:00
|
|
|
// IsDefaultVersion returns true if Version is empty or DefaultVersion.
|
|
|
|
func IsDefaultVersion() bool {
|
|
|
|
return Version == "" || Version == DefaultVersion
|
|
|
|
}
|