|
|
|
|
@ -8,7 +8,9 @@ import ( |
|
|
|
|
"os" |
|
|
|
|
"path/filepath" |
|
|
|
|
"runtime" |
|
|
|
|
"strconv" |
|
|
|
|
"strings" |
|
|
|
|
"sync" |
|
|
|
|
|
|
|
|
|
"tailscale.com/syncs" |
|
|
|
|
) |
|
|
|
|
@ -74,3 +76,31 @@ func IsWindowsGUI() bool { |
|
|
|
|
exe = filepath.Base(exe) |
|
|
|
|
return strings.EqualFold(exe, "tailscale-ipn.exe") || strings.EqualFold(exe, "tailscale-ipn") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
isUnstableOnce sync.Once |
|
|
|
|
isUnstableBuild bool |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// IsUnstableBuild reports whether this is an unstable build.
|
|
|
|
|
// That is, whether its minor version number is odd.
|
|
|
|
|
func IsUnstableBuild() bool { |
|
|
|
|
isUnstableOnce.Do(initUnstable) |
|
|
|
|
return isUnstableBuild |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func initUnstable() { |
|
|
|
|
_, rest, ok := strings.Cut(Short, ".") |
|
|
|
|
if !ok { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
minorStr, _, ok := strings.Cut(rest, ".") |
|
|
|
|
if !ok { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
minor, err := strconv.Atoi(minorStr) |
|
|
|
|
if err != nil { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
isUnstableBuild = minor%2 == 1 |
|
|
|
|
} |
|
|
|
|
|