// 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 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 }