tailscale/version/version.go
David Anderson 9ad36d17a3 version: undo previous "optimization", do more work lazily
Commit 59c254579e moved a lot of work
from functions that could be eliminated at compile time (because
tests against runtime.GOOS are compile-time constant), into code
that must always run before main().

So, revert that, and instead optimize the package only by moving the
remaining string processing code behind sync.Onces.

Signed-off-by: David Anderson <danderson@tailscale.com>
2023-02-10 15:27:14 -08:00

103 lines
3.3 KiB
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Package version provides the version that the binary was built at.
package version
import (
"runtime/debug"
"strings"
tailscaleroot "tailscale.com"
)
// Long is a full version number for this build, of the form
// "x.y.z-commithash" for builds stamped in the usual way (see
// build_dist.sh in the root) or, for binaries built by hand with the
// go tool, it's of the form "1.23.0-dev20220316-t29837428937{,-dirty}"
// where "1.23.0" comes from ../VERSION.txt and the part after dev
// is YYYYMMDD of the commit time, and the part after -t is the commit
// hash. The dirty suffix is whether there are uncommitted changes.
var Long = ""
// Short is a short version number for this build, of the form
// "x.y.z" for builds stamped in the usual way (see
// build_dist.sh in the root) or, for binaries built by hand with the
// go tool, it's like Long's dev form, but ending at the date part,
// of the form "1.23.0-dev20220316".
var Short = ""
func init() {
defer func() {
// Must be run after Short has been initialized, easiest way to do that
// is a defer.
majorMinorPatch, _, _ = strings.Cut(Short, "-")
}()
if Long != "" && Short != "" {
// Built in the recommended way, using build_dist.sh.
return
}
// Otherwise, make approximate version info using Go 1.18's built-in git
// stamping.
bi, ok := debug.ReadBuildInfo()
if !ok {
Long = strings.TrimSpace(tailscaleroot.VersionDotTxt) + "-ERR-BuildInfo"
Short = Long
return
}
var dirty string // "-dirty" suffix if dirty
var commitDate string
for _, s := range bi.Settings {
switch s.Key {
case "vcs.revision":
GitCommit = s.Value
case "vcs.time":
if len(s.Value) >= len("yyyy-mm-dd") {
commitDate = s.Value[:len("yyyy-mm-dd")]
commitDate = strings.ReplaceAll(commitDate, "-", "")
}
case "vcs.modified":
if s.Value == "true" {
dirty = "-dirty"
GitDirty = true
}
}
}
commitHashAbbrev := GitCommit
if len(commitHashAbbrev) >= 9 {
commitHashAbbrev = commitHashAbbrev[:9]
}
// Backup path, using Go 1.18's built-in git stamping.
Short = strings.TrimSpace(tailscaleroot.VersionDotTxt) + "-dev" + commitDate
Long = Short + "-t" + commitHashAbbrev + dirty
}
// GitCommit, if non-empty, is the git commit of the
// github.com/tailscale/tailscale repository at which Tailscale was
// built. Its format is the one returned by `git describe --always
// --exclude "*" --dirty --abbrev=200`.
var GitCommit = ""
// GitDirty is whether Go stamped the binary as having dirty version
// control changes in the working directory (debug.ReadBuildInfo
// setting "vcs.modified" was true).
var GitDirty bool
// ExtraGitCommit, if non-empty, is the git commit of a "supplemental"
// repository at which Tailscale was built. Its format is the same as
// gitCommit.
//
// ExtraGitCommit is used to track the source revision when the main
// Tailscale repository is integrated into and built from another
// repository (for example, Tailscale's proprietary code, or the
// Android OSS repository). Together, GitCommit and ExtraGitCommit
// exactly describe what repositories and commits were used in a
// build.
var ExtraGitCommit = ""
// majorMinorPatch is the major.minor.patch portion of Short.
var majorMinorPatch string