sq/cli/buildinfo/buildinfo.go
Neil O'Toole c5cf6c0cc0
#217: Configurable timestamp format (#218)
* Moved time functions from pkg stringz to pkg timez

* Refactor options.Opt

* wip: initial work on configurable time layout

* wip: most printers now respect format.datetime and friends

* Folded pkg timefmt into timez

* Refactor options.Opt; refine options

* Add 'sq config set OPTION --help' mechanism

* Finished completion of OptDateFormatAsNumber and OptTimeFormatAsNumber
2023-05-06 20:36:34 -06:00

111 lines
2.5 KiB
Go

// Package buildinfo hosts build info variables populated via ldflags.
//
// For testing, you can override the build version
// using envar SQ_BUILD_VERSION (panics if not a valid semver).
package buildinfo
import (
"fmt"
"os"
"strings"
"github.com/neilotoole/sq/libsq/core/timez"
"github.com/neilotoole/sq/libsq/core/lg/lga"
"golang.org/x/exp/slog"
"golang.org/x/mod/semver"
)
// DefaultVersion is the default value for Version if not
// set via ldflags.
const DefaultVersion = "v0.0.0-dev"
var (
// Version is the build version. If not set at build time via
// ldflags, Version takes the value of DefaultVersion.
Version = DefaultVersion
// Commit is the commit hash.
Commit string
// Timestamp is the timestamp of when the cli was built.
Timestamp string
)
// BuildInfo encapsulates Version, Commit and Timestamp.
type BuildInfo struct {
Version string `json:"version"`
Commit string `json:"commit,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
}
// String returns a string representation of BuildInfo.
func (bi BuildInfo) String() string {
s := bi.Version
if bi.Commit != "" {
s += " " + bi.Commit
}
if bi.Timestamp != "" {
s += " " + bi.Timestamp
}
return s
}
// 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),
slog.String(lga.Timestamp, bi.Timestamp))
return gv
}
// Info returns BuildInfo.
func Info() BuildInfo {
return BuildInfo{
Version: Version,
Commit: Commit,
Timestamp: Timestamp,
}
}
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.
panic(fmt.Sprintf("Invalid BuildInfo.Version value: %s", Version))
}
if Timestamp != "" {
// Make sure Timestamp is normalized
t := timez.TimestampToRFC3339(Timestamp)
if t != "" {
Timestamp = t
}
}
if v, ok := os.LookupEnv(EnvOverrideVersion); ok {
if !semver.IsValid(v) {
panic(fmt.Sprintf("Invalid semver value from %s: %s", EnvOverrideVersion, v))
}
Version = v
}
}
// EnvOverrideVersion is used for testing build version, e.g. for
// config upgrades.
const EnvOverrideVersion = `SQ_BUILD_VERSION`
// IsDefaultVersion returns true if Version is empty or DefaultVersion.
func IsDefaultVersion() bool {
return Version == "" || Version == DefaultVersion
}