The version moves from the header to a "Powered by Jarl" footer. A build of a release tag (HEAD tagged v<VERSION>, no tracked changes; the release workflow sets RELEASE_TAG) shows and links the release; any other build shows and links its commit, marked -modified with uncommitted changes. jarld version, jarl --version, /status and /auth/whoami report the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
95 lines
2.6 KiB
Go
95 lines
2.6 KiB
Go
// Package version holds Jarl's version, set at build time with
|
|
//
|
|
// go build -ldflags "-X jarl/internal/version.Version=1.2.3 -X jarl/internal/version.Tag=v1.2.3"
|
|
//
|
|
// The Makefile sets Version from the VERSION file, and Tag only when the
|
|
// build is of that release: HEAD is the tag v<VERSION> and no tracked file
|
|
// is changed. Other builds are identified by their commit, which Go
|
|
// records from git by itself.
|
|
package version
|
|
|
|
import (
|
|
"runtime/debug"
|
|
"sync"
|
|
)
|
|
|
|
// Version is the Jarl version (the VERSION file).
|
|
var Version = "0.1.0-dev"
|
|
|
|
// Tag is the release tag the build is of ("" when it isn't a release).
|
|
var Tag = ""
|
|
|
|
// Commit is the git commit the build is of. It is read from the build
|
|
// information when not set at build time.
|
|
var Commit = ""
|
|
|
|
// Repo is Jarl's source repository.
|
|
const Repo = "https://gitea.adbraun.lol/adam/jarl"
|
|
|
|
// Build describes what a binary was built from.
|
|
type Build struct {
|
|
Version string `json:"version"`
|
|
Tag string `json:"tag,omitempty"`
|
|
Commit string `json:"commit,omitempty"`
|
|
Modified bool `json:"modified,omitempty"` // built with uncommitted changes
|
|
// Label is the short form to show: the tag of a release, otherwise
|
|
// the abbreviated commit (or the version when the commit is unknown).
|
|
Label string `json:"label"`
|
|
// URL is the release or commit in the repository.
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
var info = sync.OnceValue(func() Build {
|
|
commit, modified := Commit, false
|
|
if bi, ok := debug.ReadBuildInfo(); ok {
|
|
for _, s := range bi.Settings {
|
|
switch s.Key {
|
|
case "vcs.revision":
|
|
if commit == "" {
|
|
commit = s.Value
|
|
}
|
|
case "vcs.modified":
|
|
modified = s.Value == "true"
|
|
}
|
|
}
|
|
}
|
|
return describe(Version, Tag, commit, modified)
|
|
})
|
|
|
|
func describe(version, tag, commit string, modified bool) Build {
|
|
b := Build{Version: version, Tag: tag, Commit: commit, Modified: modified}
|
|
switch {
|
|
case tag != "":
|
|
b.Modified = false // the Makefile only sets Tag for clean trees
|
|
b.Label, b.URL = tag, Repo+"/releases/tag/"+tag
|
|
case commit != "":
|
|
b.Label, b.URL = short(commit), Repo+"/commit/"+commit
|
|
if modified {
|
|
b.Label += "-modified"
|
|
}
|
|
default:
|
|
b.Label, b.URL = version, Repo
|
|
}
|
|
return b
|
|
}
|
|
|
|
// Info describes this build.
|
|
func Info() Build { return info() }
|
|
|
|
// String is the version for logs and 'version' commands: "0.2.0" for a
|
|
// release, otherwise the version and the commit ("0.2.0-dev (a1b2c3d4e5f6)").
|
|
func String() string {
|
|
b := Info()
|
|
if b.Tag != "" || b.Commit == "" {
|
|
return b.Version
|
|
}
|
|
return b.Version + " (" + b.Label + ")"
|
|
}
|
|
|
|
func short(commit string) string {
|
|
if len(commit) > 12 {
|
|
return commit[:12]
|
|
}
|
|
return commit
|
|
}
|