@ -5,93 +5,29 @@
package version
package version
import (
import (
"os"
"path/filepath"
"runtime"
"runtime/debug"
"runtime/debug"
"strconv"
"strings"
"strings"
tailscaleroot "tailscale.com"
tailscaleroot "tailscale.com"
)
)
var (
// Long is a full version number for this build, of the form
// Long is a full version number for this build, of the form
// "x.y.z-commithash" for builds stamped in the usual way (see
// "x.y.z-commithash" for builds stamped in the usual way (see build_dist.sh
// build_dist.sh in the root) or, for binaries built by hand with the
// in the root) or, for binaries built by hand with the go tool, it's of the
// go tool, it's of the form "1.23.0-dev20220316-t29837428937{,-dirty}"
// form "1.23.0-dev20220316-t29837428937{,-dirty}" where "1.23.0" comes from
// where "1.23.0" comes from ../VERSION.txt and the part after dev
// ../VERSION.txt and the part after dev is YYYYMMDD of the commit time, and
// is YYYYMMDD of the commit time, and the part after -t is the commit
// the part after -t is the commit hash. The dirty suffix is whether there
// hash. The dirty suffix is whether there are uncommitted changes.
// are uncommitted changes.
var Long = ""
Long string
// Short is a short version number for this build, of the form
// Short is a short version number for this build, of the form
// "x.y.z" for builds stamped in the usual way (see
// "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
// 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,
// go tool, it's like Long's dev form, but ending at the date part,
// of the form "1.23.0-dev20220316".
// of the form "1.23.0-dev20220316".
var Short = ""
Short string
// 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`.
GitCommit string
// GitDirty is whether Go stamped the binary as having dirty version
// control changes in the working directory (debug.ReadBuildInfo
// setting "vcs.modified" was true).
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.
ExtraGitCommit = ""
// isUnstable is whether the current build appears to be an unstable, i.e. with
// an odd minor version number.
isUnstable bool
// legacyOS is runtime.GOOS, except on apple devices where it's either "iOS" or
// "macOS" (with that exact case).
//
// This used to be a thing because Go reported both macOS and iOS as "darwin"
// and we needed to tell them apart. But then Go learned GOOS=ios and
// GOOS=darwin as separate things, but we're still stuck with this function
// because of the odd casing we picked, which has ossified into databases.
legacyOS string
// isMobile is whether the current build is for a mobile device.
isMobile bool
// isSandboxedMacOS is whether the current binary is any binary in the mac store
// or standalone sysext mac apps.
isSandboxedMacOS bool
// isMacSysExt is whether the current binary is the mac system extension binary.
isMacSysExt bool
// isWindowsGUI is whether the current binary is the Windows GUI binary.
isWindowsGUI bool
// majorMinorPatch is the major.minor.patch portion of Short.
majorMinorPatch string
)
func init ( ) {
func init ( ) {
initVersion ( )
initUnstable ( )
initMiscTraits ( )
}
func initVersion ( ) {
defer func ( ) {
defer func ( ) {
// Must be run after Short has been initialized, easiest way to do that
// Must be run after Short has been initialized, easiest way to do that
// is a defer.
// is a defer.
@ -139,38 +75,28 @@ func initVersion() {
Long = Short + "-t" + commitHashAbbrev + dirty
Long = Short + "-t" + commitHashAbbrev + dirty
}
}
func initUnstable ( ) {
// GitCommit, if non-empty, is the git commit of the
_ , rest , ok := strings . Cut ( Short , "." )
// github.com/tailscale/tailscale repository at which Tailscale was
if ! ok {
// built. Its format is the one returned by `git describe --always
return
// --exclude "*" --dirty --abbrev=200`.
}
var GitCommit = ""
minorStr , _ , ok := strings . Cut ( rest , "." )
if ! ok {
// GitDirty is whether Go stamped the binary as having dirty version
return
// control changes in the working directory (debug.ReadBuildInfo
}
// setting "vcs.modified" was true).
minor , err := strconv . Atoi ( minorStr )
var GitDirty bool
if err != nil {
return
// ExtraGitCommit, if non-empty, is the git commit of a "supplemental"
}
// repository at which Tailscale was built. Its format is the same as
isUnstable = minor % 2 == 1
// gitCommit.
}
//
// ExtraGitCommit is used to track the source revision when the main
func initMiscTraits ( ) {
// Tailscale repository is integrated into and built from another
exe , _ := os . Executable ( )
// repository (for example, Tailscale's proprietary code, or the
base := filepath . Base ( exe )
// Android OSS repository). Together, GitCommit and ExtraGitCommit
// exactly describe what repositories and commits were used in a
legacyOS = runtime . GOOS
// build.
switch runtime . GOOS {
var ExtraGitCommit = ""
case "darwin" :
legacyOS = "macOS"
// majorMinorPatch is the major.minor.patch portion of Short.
isMacSysExt = strings . HasPrefix ( base , "io.tailscale.ipn.macsys.network-extension" )
var majorMinorPatch string
isSandboxedMacOS = isMacSysExt || strings . HasSuffix ( exe , "/Contents/MacOS/Tailscale" ) || strings . HasSuffix ( exe , "/Contents/MacOS/IPNExtension" )
case "ios" :
legacyOS = "iOS"
isMobile = true
case "android" :
isMobile = true
case "windows" :
isWindowsGUI = strings . EqualFold ( base , "tailscale-ipn.exe" ) || strings . EqualFold ( base , "tailscale-ipn" )
}
}