Files
coder/buildinfo/buildinfo.go
T
Asher 18595791c0 feat: add version to footer (#882)
* Add endpoint for getting build info

* Add build info XService

* Add version with link to page footer

Partially addresses #376.

* Lift buildinfo package
2022-04-07 12:18:58 -05:00

84 lines
1.7 KiB
Go

package buildinfo
import (
"path"
"runtime/debug"
"sync"
"time"
"golang.org/x/mod/semver"
)
var (
buildInfo *debug.BuildInfo
buildInfoValid bool
readBuildInfo sync.Once
// Injected with ldflags at build!
tag string
)
// Version returns the semantic version of the build.
// Use golang.org/x/mod/semver to compare versions.
func Version() string {
revision, valid := revision()
if valid {
revision = "+" + revision[:7]
}
if tag == "" {
return "v0.0.0-devel" + revision
}
if semver.Build(tag) == "" {
tag += revision
}
return "v" + tag
}
// ExternalURL returns a URL referencing the current Coder version.
// For production builds, this will link directly to a release.
// For development builds, this will link to a commit.
func ExternalURL() string {
repo := "https://github.com/coder/coder"
revision, valid := revision()
if !valid {
return repo
}
return path.Join(repo, "commit", revision)
}
// Time returns when the Git revision was published.
func Time() (time.Time, bool) {
value, valid := find("vcs.time")
if !valid {
return time.Time{}, false
}
parsed, err := time.Parse(time.RFC3339, value)
if err != nil {
panic("couldn't parse time: " + err.Error())
}
return parsed, true
}
// revision returns the Git hash of the build.
func revision() (string, bool) {
return find("vcs.revision")
}
// find panics if a setting with the specific key was not
// found in the build info.
func find(key string) (string, bool) {
readBuildInfo.Do(func() {
buildInfo, buildInfoValid = debug.ReadBuildInfo()
})
if !buildInfoValid {
panic("couldn't read build info")
}
for _, setting := range buildInfo.Settings {
if setting.Key != key {
continue
}
return setting.Value, true
}
return "", false
}