mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
version/mkversion: add documentation, rename internal terminology
Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
parent
1dadbbb72a
commit
8ed27d65ef
@ -23,27 +23,61 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VersionInfo is version information extracted from a git checkout.
|
||||||
type VersionInfo struct {
|
type VersionInfo struct {
|
||||||
Short string
|
// Short is the short version string. See the documentation of version.Short
|
||||||
Long string
|
// for possible values.
|
||||||
OSSHash string
|
Short string
|
||||||
CorpHash string
|
// Long is the long version string. See the documentation for version.Long
|
||||||
Xcode string // For embedding into Xcode metadata (iOS and macsys)
|
// for possible values.
|
||||||
XcodeMacOS string // For embedding into Xcode metadata (macOS)
|
Long string
|
||||||
Winres string // For embedding into Windows metadata
|
// GitHash is the git hash of the tailscale.com Go module.
|
||||||
OSSDate string // Unix timestamp of commit date (git: %ct)
|
GitHash string
|
||||||
CorpDate string // Unix timestamp of commit date (git: %ct)
|
// OtherHash is the git hash of a supplemental git repository, if any. For
|
||||||
Track string
|
// example, the commit of the tailscale-android repository.
|
||||||
|
OtherHash string
|
||||||
|
// Xcode is the version string that gets embedded into Xcode builds for the
|
||||||
|
// Tailscale iOS app and macOS standalone (aka "macsys") app.
|
||||||
|
//
|
||||||
|
// It is the same as Short, but with 100 added to the major version number.
|
||||||
|
// This is because Apple requires monotonically increasing version numbers,
|
||||||
|
// and very early builds of Tailscale used a single incrementing integer,
|
||||||
|
// which the Apple interprets as the major version number. When we switched
|
||||||
|
// to the current scheme, we started the major version number at 100 (v0,
|
||||||
|
// plus 100) to make the transition.
|
||||||
|
Xcode string
|
||||||
|
// XcodeMacOS is the version string that gets embedded into Xcode builds for
|
||||||
|
// the Tailscale macOS app store app.
|
||||||
|
//
|
||||||
|
// This used to be the same as Xcode, but at some point Xcode reverted to
|
||||||
|
// auto-incrementing build numbers instead of using the version we embedded.
|
||||||
|
// As a result, we had to alter the version scheme again, and switched to
|
||||||
|
// GitHash's commit date, in the format "YYYY.DDD.HHMMSS"
|
||||||
|
XcodeMacOS string
|
||||||
|
// Winres is the version string that gets embedded into Windows exe
|
||||||
|
// metadata. It is of the form "x,y,z,0".
|
||||||
|
Winres string
|
||||||
|
// GitDate is the unix timestamp of GitHash's commit date.
|
||||||
|
GitDate string
|
||||||
|
// OtherDate is the unix timestamp of OtherHash's commit date, if any.
|
||||||
|
OtherDate string
|
||||||
|
// Track is the release track of this build: "stable" if the minor version
|
||||||
|
// number is even, "unstable" if it's odd.
|
||||||
|
Track string
|
||||||
|
// MSIProductCodes is a map of Windows CPU architecture names to UUIDv5
|
||||||
|
// hashes that uniquely identify the version of the build. These are used in
|
||||||
|
// the MSI installer logic to uniquely identify particular builds.
|
||||||
MSIProductCodes map[string]string
|
MSIProductCodes map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String returns v's information as shell variable assignments.
|
||||||
func (v VersionInfo) String() string {
|
func (v VersionInfo) String() string {
|
||||||
f := fmt.Fprintf
|
f := fmt.Fprintf
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
f(&b, "VERSION_SHORT=%q\n", v.Short)
|
f(&b, "VERSION_SHORT=%q\n", v.Short)
|
||||||
f(&b, "VERSION_LONG=%q\n", v.Long)
|
f(&b, "VERSION_LONG=%q\n", v.Long)
|
||||||
f(&b, "VERSION_GIT_HASH=%q\n", v.OSSHash)
|
f(&b, "VERSION_GIT_HASH=%q\n", v.GitHash)
|
||||||
f(&b, "VERSION_EXTRA_HASH=%q\n", v.CorpHash)
|
f(&b, "VERSION_EXTRA_HASH=%q\n", v.OtherHash)
|
||||||
f(&b, "VERSION_XCODE=%q\n", v.Xcode)
|
f(&b, "VERSION_XCODE=%q\n", v.Xcode)
|
||||||
f(&b, "VERSION_XCODE_MACOS=%q\n", v.XcodeMacOS)
|
f(&b, "VERSION_XCODE_MACOS=%q\n", v.XcodeMacOS)
|
||||||
f(&b, "VERSION_WINRES=%q\n", v.Winres)
|
f(&b, "VERSION_WINRES=%q\n", v.Winres)
|
||||||
@ -71,32 +105,34 @@ func Info() VersionInfo {
|
|||||||
func InfoFrom(dir string) (VersionInfo, error) {
|
func InfoFrom(dir string) (VersionInfo, error) {
|
||||||
runner := dirRunner(dir)
|
runner := dirRunner(dir)
|
||||||
|
|
||||||
var v verInfo
|
|
||||||
var err error
|
var err error
|
||||||
v.corpHash, err = runner.output("git", "rev-parse", "HEAD")
|
otherHash, err := runner.output("git", "rev-parse", "HEAD")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return VersionInfo{}, err
|
return VersionInfo{}, err
|
||||||
}
|
}
|
||||||
v.corpDate, err = runner.output("git", "log", "-n1", "--format=%ct", "HEAD")
|
otherDate, err := runner.output("git", "log", "-n1", "--format=%ct", "HEAD")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return VersionInfo{}, err
|
return VersionInfo{}, err
|
||||||
}
|
}
|
||||||
if !runner.ok("git", "diff-index", "--quiet", "HEAD") {
|
if !runner.ok("git", "diff-index", "--quiet", "HEAD") {
|
||||||
v.corpHash = v.corpHash + "-dirty"
|
otherHash = otherHash + "-dirty"
|
||||||
}
|
}
|
||||||
|
|
||||||
ossHash, ossDir, err := parseGoMod(runner)
|
var v verInfo
|
||||||
|
hash, dir, err := parseGoMod(runner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return VersionInfo{}, err
|
return VersionInfo{}, err
|
||||||
}
|
}
|
||||||
if ossHash != "" {
|
if hash != "" {
|
||||||
v.ossInfo, err = infoFromCache(ossHash, runner)
|
v, err = infoFromCache(hash, runner)
|
||||||
} else {
|
} else {
|
||||||
v.ossInfo, err = infoFromDir(ossDir)
|
v, err = infoFromDir(dir)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return VersionInfo{}, err
|
return VersionInfo{}, err
|
||||||
}
|
}
|
||||||
|
v.otherHash = otherHash
|
||||||
|
v.otherDate = otherDate
|
||||||
|
|
||||||
return mkOutput(v)
|
return mkOutput(v)
|
||||||
|
|
||||||
@ -124,8 +160,8 @@ func mkOutput(v verInfo) (VersionInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var hashes string
|
var hashes string
|
||||||
if v.corpHash != "" {
|
if v.otherHash != "" {
|
||||||
hashes = "-g" + shortHash(v.corpHash)
|
hashes = "-g" + shortHash(v.otherHash)
|
||||||
}
|
}
|
||||||
if v.hash != "" {
|
if v.hash != "" {
|
||||||
hashes = "-t" + shortHash(v.hash) + hashes
|
hashes = "-t" + shortHash(v.hash) + hashes
|
||||||
@ -143,26 +179,26 @@ func mkOutput(v verInfo) (VersionInfo, error) {
|
|||||||
// based it on the actual version number we'd run into issues when doing
|
// based it on the actual version number we'd run into issues when doing
|
||||||
// cherrypick stable builds from a release branch after unstable builds from
|
// cherrypick stable builds from a release branch after unstable builds from
|
||||||
// HEAD).
|
// HEAD).
|
||||||
corpSec, err := strconv.ParseInt(v.corpDate, 10, 64)
|
otherSec, err := strconv.ParseInt(v.otherDate, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return VersionInfo{}, fmt.Errorf("Culd not parse corpDate %q: %w", v.corpDate, err)
|
return VersionInfo{}, fmt.Errorf("Culd not parse otherDate %q: %w", v.otherDate, err)
|
||||||
}
|
}
|
||||||
corpTime := time.Unix(corpSec, 0).UTC()
|
otherTime := time.Unix(otherSec, 0).UTC()
|
||||||
// We started to need to do this in 2023, and the last Apple-generated
|
// We started to need to do this in 2023, and the last Apple-generated
|
||||||
// incrementing build number was 273. To avoid using up the space, we
|
// incrementing build number was 273. To avoid using up the space, we
|
||||||
// use <year - 1750> as the major version (thus 273.*, 274.* in 2024, etc.),
|
// use <year - 1750> as the major version (thus 273.*, 274.* in 2024, etc.),
|
||||||
// so that we we're still in the same range. This way if Apple goes back to
|
// so that we we're still in the same range. This way if Apple goes back to
|
||||||
// auto-incrementing the number for us, we can go back to it with
|
// auto-incrementing the number for us, we can go back to it with
|
||||||
// reasonable-looking numbers.
|
// reasonable-looking numbers.
|
||||||
xcodeMacOS := fmt.Sprintf("%d.%d.%d", corpTime.Year()-1750, corpTime.YearDay(), corpTime.Hour()*60*60+corpTime.Minute()*60+corpTime.Second())
|
xcodeMacOS := fmt.Sprintf("%d.%d.%d", otherTime.Year()-1750, otherTime.YearDay(), otherTime.Hour()*60*60+otherTime.Minute()*60+otherTime.Second())
|
||||||
|
|
||||||
return VersionInfo{
|
return VersionInfo{
|
||||||
Short: fmt.Sprintf("%d.%d.%d", v.major, v.minor, v.patch),
|
Short: fmt.Sprintf("%d.%d.%d", v.major, v.minor, v.patch),
|
||||||
Long: fmt.Sprintf("%d.%d.%d%s%s", v.major, v.minor, v.patch, changeSuffix, hashes),
|
Long: fmt.Sprintf("%d.%d.%d%s%s", v.major, v.minor, v.patch, changeSuffix, hashes),
|
||||||
OSSHash: fmt.Sprintf("%s", v.hash),
|
GitHash: fmt.Sprintf("%s", v.hash),
|
||||||
OSSDate: fmt.Sprintf("%s", v.ossInfo.date),
|
GitDate: fmt.Sprintf("%s", v.date),
|
||||||
CorpHash: fmt.Sprintf("%s", v.corpHash),
|
OtherHash: fmt.Sprintf("%s", v.otherHash),
|
||||||
CorpDate: fmt.Sprintf("%s", v.corpDate),
|
OtherDate: fmt.Sprintf("%s", v.otherDate),
|
||||||
Xcode: fmt.Sprintf("%d.%d.%d", v.major+100, v.minor, v.patch),
|
Xcode: fmt.Sprintf("%d.%d.%d", v.major+100, v.minor, v.patch),
|
||||||
XcodeMacOS: xcodeMacOS,
|
XcodeMacOS: xcodeMacOS,
|
||||||
Winres: fmt.Sprintf("%d,%d,%d,0", v.major, v.minor, v.patch),
|
Winres: fmt.Sprintf("%d,%d,%d,0", v.major, v.minor, v.patch),
|
||||||
@ -192,12 +228,12 @@ func makeMSIProductCodes(v verInfo, track string) map[string]string {
|
|||||||
func gitRootDir() (string, error) {
|
func gitRootDir() (string, error) {
|
||||||
top, err := exec.Command("git", "rev-parse", "--show-toplevel").Output()
|
top, err := exec.Command("git", "rev-parse", "--show-toplevel").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to find git top level (not in corp git?): %w", err)
|
return "", fmt.Errorf("failed to find git top level: %w", err)
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(string(top)), nil
|
return strings.TrimSpace(string(top)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseGoMod(runner dirRunner) (ossShortHash, localCheckout string, err error) {
|
func parseGoMod(runner dirRunner) (shortHash, localCheckout string, err error) {
|
||||||
goBin := filepath.Join(runtime.GOROOT(), "bin", "go"+exe())
|
goBin := filepath.Join(runtime.GOROOT(), "bin", "go"+exe())
|
||||||
if !strings.HasPrefix(goBin, "/") {
|
if !strings.HasPrefix(goBin, "/") {
|
||||||
// GOROOT got -trimpath'd, fall back to hoping $PATH has a
|
// GOROOT got -trimpath'd, fall back to hoping $PATH has a
|
||||||
@ -230,7 +266,7 @@ func parseGoMod(runner dirRunner) (ossShortHash, localCheckout string, err error
|
|||||||
if r.Path != "tailscale.com" {
|
if r.Path != "tailscale.com" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
shortHash := r.Version[strings.LastIndex(r.Version, "-")+1:]
|
shortHash = r.Version[strings.LastIndex(r.Version, "-")+1:]
|
||||||
return shortHash, "", nil
|
return shortHash, "", nil
|
||||||
}
|
}
|
||||||
return "", "", fmt.Errorf("failed to find tailscale.com module in go.mod")
|
return "", "", fmt.Errorf("failed to find tailscale.com module in go.mod")
|
||||||
@ -244,25 +280,22 @@ func exe() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type verInfo struct {
|
type verInfo struct {
|
||||||
ossInfo
|
|
||||||
corpHash string
|
|
||||||
corpDate string
|
|
||||||
}
|
|
||||||
|
|
||||||
// unknownPatchVersion is the patch version used when the oss package
|
|
||||||
// doesn't contain enough version information to derive the correct
|
|
||||||
// version. Such builds only get used when generating bug reports in
|
|
||||||
// an ephemeral working environment, so will never be distributed. As
|
|
||||||
// such, we use a highly visible sentinel patch number.
|
|
||||||
const unknownPatchVersion = 9999999
|
|
||||||
|
|
||||||
type ossInfo struct {
|
|
||||||
major, minor, patch int
|
major, minor, patch int
|
||||||
changeCount int
|
changeCount int
|
||||||
hash string
|
hash string
|
||||||
date string
|
date string
|
||||||
|
|
||||||
|
otherHash string
|
||||||
|
otherDate string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unknownPatchVersion is the patch version used when the tailscale.com package
|
||||||
|
// doesn't contain enough version information to derive the correct version.
|
||||||
|
// Such builds only get used when generating bug reports in an ephemeral working
|
||||||
|
// environment, so will never be distributed. As such, we use a highly visible
|
||||||
|
// sentinel patch number.
|
||||||
|
const unknownPatchVersion = 9999999
|
||||||
|
|
||||||
func isBareRepo(r dirRunner) (bool, error) {
|
func isBareRepo(r dirRunner) (bool, error) {
|
||||||
s, err := r.output("git", "rev-parse", "--is-bare-repository")
|
s, err := r.output("git", "rev-parse", "--is-bare-repository")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -272,71 +305,71 @@ func isBareRepo(r dirRunner) (bool, error) {
|
|||||||
return o == "true", nil
|
return o == "true", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func infoFromCache(shortHash string, runner dirRunner) (ossInfo, error) {
|
func infoFromCache(shortHash string, runner dirRunner) (verInfo, error) {
|
||||||
cacheDir, err := os.UserCacheDir()
|
cacheDir, err := os.UserCacheDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, fmt.Errorf("Getting user cache dir: %w", err)
|
return verInfo{}, fmt.Errorf("Getting user cache dir: %w", err)
|
||||||
}
|
}
|
||||||
ossCache := filepath.Join(cacheDir, "tailscale-oss")
|
tailscaleCache := filepath.Join(cacheDir, "tailscale-oss")
|
||||||
r := dirRunner(ossCache)
|
r := dirRunner(tailscaleCache)
|
||||||
|
|
||||||
cloneRequired := false
|
cloneRequired := false
|
||||||
if _, err := os.Stat(ossCache); err != nil {
|
if _, err := os.Stat(tailscaleCache); err != nil {
|
||||||
cloneRequired = true
|
cloneRequired = true
|
||||||
} else {
|
} else {
|
||||||
isBare, err := isBareRepo(r)
|
isBare, err := isBareRepo(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
if isBare {
|
if isBare {
|
||||||
cloneRequired = true
|
cloneRequired = true
|
||||||
if err := os.RemoveAll(ossCache); err != nil {
|
if err := os.RemoveAll(tailscaleCache); err != nil {
|
||||||
return ossInfo{}, fmt.Errorf("removing old cache dir failed: %w", err)
|
return verInfo{}, fmt.Errorf("removing old cache dir failed: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cloneRequired {
|
if cloneRequired {
|
||||||
if !runner.ok("git", "clone", "https://github.com/tailscale/tailscale", ossCache) {
|
if !runner.ok("git", "clone", "https://github.com/tailscale/tailscale", tailscaleCache) {
|
||||||
return ossInfo{}, fmt.Errorf("cloning OSS repo failed")
|
return verInfo{}, fmt.Errorf("cloning OSS repo failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !r.ok("git", "cat-file", "-e", shortHash) {
|
if !r.ok("git", "cat-file", "-e", shortHash) {
|
||||||
if !r.ok("git", "fetch", "origin") {
|
if !r.ok("git", "fetch", "origin") {
|
||||||
return ossInfo{}, fmt.Errorf("updating OSS repo failed")
|
return verInfo{}, fmt.Errorf("updating OSS repo failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash, err := r.output("git", "rev-parse", shortHash)
|
hash, err := r.output("git", "rev-parse", shortHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
date, err := r.output("git", "log", "-n1", "--format=%ct", shortHash)
|
date, err := r.output("git", "log", "-n1", "--format=%ct", shortHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
baseHash, err := r.output("git", "rev-list", "--max-count=1", hash, "--", "VERSION.txt")
|
baseHash, err := r.output("git", "rev-list", "--max-count=1", hash, "--", "VERSION.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
s, err := r.output("git", "show", baseHash+":VERSION.txt")
|
s, err := r.output("git", "show", baseHash+":VERSION.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
major, minor, patch, err := parseVersion(s)
|
major, minor, patch, err := parseVersion(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
s, err = r.output("git", "rev-list", "--count", hash, "^"+baseHash)
|
s, err = r.output("git", "rev-list", "--count", hash, "^"+baseHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
changeCount, err := strconv.Atoi(s)
|
changeCount, err := strconv.Atoi(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, fmt.Errorf("infoFromCache: parsing changeCount %q: %w", changeCount, err)
|
return verInfo{}, fmt.Errorf("infoFromCache: parsing changeCount %q: %w", changeCount, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ossInfo{
|
return verInfo{
|
||||||
major: major,
|
major: major,
|
||||||
minor: minor,
|
minor: minor,
|
||||||
patch: patch,
|
patch: patch,
|
||||||
@ -346,17 +379,17 @@ func infoFromCache(shortHash string, runner dirRunner) (ossInfo, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func infoFromDir(dir string) (ossInfo, error) {
|
func infoFromDir(dir string) (verInfo, error) {
|
||||||
r := dirRunner(dir)
|
r := dirRunner(dir)
|
||||||
gitDir := filepath.Join(dir, ".git")
|
gitDir := filepath.Join(dir, ".git")
|
||||||
if _, err := os.Stat(gitDir); err != nil {
|
if _, err := os.Stat(gitDir); err != nil {
|
||||||
// Raw directory fetch, get as much info as we can and make up the rest.
|
// Raw directory fetch, get as much info as we can and make up the rest.
|
||||||
s, err := readFile(filepath.Join(dir, "VERSION.txt"))
|
s, err := readFile(filepath.Join(dir, "VERSION.txt"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
major, minor, patch, err := parseVersion(s)
|
major, minor, patch, err := parseVersion(s)
|
||||||
return ossInfo{
|
return verInfo{
|
||||||
major: major,
|
major: major,
|
||||||
minor: minor,
|
minor: minor,
|
||||||
patch: patch,
|
patch: patch,
|
||||||
@ -366,34 +399,34 @@ func infoFromDir(dir string) (ossInfo, error) {
|
|||||||
|
|
||||||
hash, err := r.output("git", "rev-parse", "HEAD")
|
hash, err := r.output("git", "rev-parse", "HEAD")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
date, err := r.output("git", "log", "-n1", "--format=%%ct", "HEAD")
|
date, err := r.output("git", "log", "-n1", "--format=%%ct", "HEAD")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
baseHash, err := r.output("git", "rev-list", "--max-count=1", hash, "--", "VERSION.txt")
|
baseHash, err := r.output("git", "rev-list", "--max-count=1", hash, "--", "VERSION.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
s, err := r.output("git", "show", baseHash+":VERSION.txt")
|
s, err := r.output("git", "show", baseHash+":VERSION.txt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
major, minor, patch, err := parseVersion(s)
|
major, minor, patch, err := parseVersion(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
s, err = r.output("git", "rev-list", "--count", hash, "^"+baseHash)
|
s, err = r.output("git", "rev-list", "--count", hash, "^"+baseHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
changeCount, err := strconv.Atoi(s)
|
changeCount, err := strconv.Atoi(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ossInfo{}, err
|
return verInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ossInfo{
|
return verInfo{
|
||||||
major: major,
|
major: major,
|
||||||
minor: minor,
|
minor: minor,
|
||||||
patch: patch,
|
patch: patch,
|
||||||
|
@ -12,28 +12,26 @@ import (
|
|||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mkInfo(gitHash, otherHash, corpDate string, major, minor, patch, changeCount int) verInfo {
|
func mkInfo(gitHash, otherHash, otherDate string, major, minor, patch, changeCount int) verInfo {
|
||||||
return verInfo{
|
return verInfo{
|
||||||
ossInfo: ossInfo{
|
major: major,
|
||||||
major: major,
|
minor: minor,
|
||||||
minor: minor,
|
patch: patch,
|
||||||
patch: patch,
|
changeCount: changeCount,
|
||||||
changeCount: changeCount,
|
hash: gitHash,
|
||||||
hash: gitHash,
|
otherHash: otherHash,
|
||||||
},
|
otherDate: otherDate,
|
||||||
corpHash: otherHash,
|
|
||||||
corpDate: corpDate,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMkversion(t *testing.T) {
|
func TestMkversion(t *testing.T) {
|
||||||
corpDate := fmt.Sprintf("%d", time.Date(2023, time.January, 27, 1, 2, 3, 4, time.UTC).Unix())
|
otherDate := fmt.Sprintf("%d", time.Date(2023, time.January, 27, 1, 2, 3, 4, time.UTC).Unix())
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
in verInfo
|
in verInfo
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{mkInfo("abcdef", "", corpDate, 0, 98, 0, 0), `
|
{mkInfo("abcdef", "", otherDate, 0, 98, 0, 0), `
|
||||||
VERSION_SHORT="0.98.0"
|
VERSION_SHORT="0.98.0"
|
||||||
VERSION_LONG="0.98.0-tabcdef"
|
VERSION_LONG="0.98.0-tabcdef"
|
||||||
VERSION_GIT_HASH="abcdef"
|
VERSION_GIT_HASH="abcdef"
|
||||||
@ -45,7 +43,7 @@ func TestMkversion(t *testing.T) {
|
|||||||
VERSION_MSIPRODUCT_AMD64="C653B075-AD91-5265-9DF8-0087D35D148D"
|
VERSION_MSIPRODUCT_AMD64="C653B075-AD91-5265-9DF8-0087D35D148D"
|
||||||
VERSION_MSIPRODUCT_ARM64="1C41380B-A742-5A3C-AF5D-DF7894DD0FB8"
|
VERSION_MSIPRODUCT_ARM64="1C41380B-A742-5A3C-AF5D-DF7894DD0FB8"
|
||||||
VERSION_MSIPRODUCT_X86="4ABDDA14-7499-5C2E-A62A-DD435C50C4CB"`},
|
VERSION_MSIPRODUCT_X86="4ABDDA14-7499-5C2E-A62A-DD435C50C4CB"`},
|
||||||
{mkInfo("abcdef", "", corpDate, 0, 98, 1, 0), `
|
{mkInfo("abcdef", "", otherDate, 0, 98, 1, 0), `
|
||||||
VERSION_SHORT="0.98.1"
|
VERSION_SHORT="0.98.1"
|
||||||
VERSION_LONG="0.98.1-tabcdef"
|
VERSION_LONG="0.98.1-tabcdef"
|
||||||
VERSION_GIT_HASH="abcdef"
|
VERSION_GIT_HASH="abcdef"
|
||||||
@ -57,7 +55,7 @@ func TestMkversion(t *testing.T) {
|
|||||||
VERSION_MSIPRODUCT_AMD64="DFD6DCF2-06D8-5D19-BDA0-FAF31E44EC23"
|
VERSION_MSIPRODUCT_AMD64="DFD6DCF2-06D8-5D19-BDA0-FAF31E44EC23"
|
||||||
VERSION_MSIPRODUCT_ARM64="A4CCF19C-372B-5007-AFD8-1AF661DFF670"
|
VERSION_MSIPRODUCT_ARM64="A4CCF19C-372B-5007-AFD8-1AF661DFF670"
|
||||||
VERSION_MSIPRODUCT_X86="FF12E937-DDC4-5868-9B63-D35B2050D4EA"`},
|
VERSION_MSIPRODUCT_X86="FF12E937-DDC4-5868-9B63-D35B2050D4EA"`},
|
||||||
{mkInfo("abcdef", "", corpDate, 1, 2, 9, 0), `
|
{mkInfo("abcdef", "", otherDate, 1, 2, 9, 0), `
|
||||||
VERSION_SHORT="1.2.9"
|
VERSION_SHORT="1.2.9"
|
||||||
VERSION_LONG="1.2.9-tabcdef"
|
VERSION_LONG="1.2.9-tabcdef"
|
||||||
VERSION_GIT_HASH="abcdef"
|
VERSION_GIT_HASH="abcdef"
|
||||||
@ -69,7 +67,7 @@ func TestMkversion(t *testing.T) {
|
|||||||
VERSION_MSIPRODUCT_AMD64="D47B5157-FF26-5A10-A94E-50E4529303A9"
|
VERSION_MSIPRODUCT_AMD64="D47B5157-FF26-5A10-A94E-50E4529303A9"
|
||||||
VERSION_MSIPRODUCT_ARM64="91D16F75-2A12-5E12-820A-67B89BF858E7"
|
VERSION_MSIPRODUCT_ARM64="91D16F75-2A12-5E12-820A-67B89BF858E7"
|
||||||
VERSION_MSIPRODUCT_X86="8F1AC1C6-B93B-5C70-802E-6AE9591FA0D6"`},
|
VERSION_MSIPRODUCT_X86="8F1AC1C6-B93B-5C70-802E-6AE9591FA0D6"`},
|
||||||
{mkInfo("abcdef", "", corpDate, 1, 15, 0, 129), `
|
{mkInfo("abcdef", "", otherDate, 1, 15, 0, 129), `
|
||||||
VERSION_SHORT="1.15.129"
|
VERSION_SHORT="1.15.129"
|
||||||
VERSION_LONG="1.15.129-tabcdef"
|
VERSION_LONG="1.15.129-tabcdef"
|
||||||
VERSION_GIT_HASH="abcdef"
|
VERSION_GIT_HASH="abcdef"
|
||||||
@ -81,7 +79,7 @@ func TestMkversion(t *testing.T) {
|
|||||||
VERSION_MSIPRODUCT_AMD64="89C96952-1FB8-5A4D-B02E-16A8060C56AA"
|
VERSION_MSIPRODUCT_AMD64="89C96952-1FB8-5A4D-B02E-16A8060C56AA"
|
||||||
VERSION_MSIPRODUCT_ARM64="DB1A2E86-66C4-5CEC-8F4C-7DB805370F3A"
|
VERSION_MSIPRODUCT_ARM64="DB1A2E86-66C4-5CEC-8F4C-7DB805370F3A"
|
||||||
VERSION_MSIPRODUCT_X86="DC57C0C3-5164-5C92-86B3-2800CEFF0540"`},
|
VERSION_MSIPRODUCT_X86="DC57C0C3-5164-5C92-86B3-2800CEFF0540"`},
|
||||||
{mkInfo("abcdef", "", corpDate, 1, 2, 0, 17), `
|
{mkInfo("abcdef", "", otherDate, 1, 2, 0, 17), `
|
||||||
VERSION_SHORT="1.2.0"
|
VERSION_SHORT="1.2.0"
|
||||||
VERSION_LONG="1.2.0-17-tabcdef"
|
VERSION_LONG="1.2.0-17-tabcdef"
|
||||||
VERSION_GIT_HASH="abcdef"
|
VERSION_GIT_HASH="abcdef"
|
||||||
@ -93,7 +91,7 @@ func TestMkversion(t *testing.T) {
|
|||||||
VERSION_MSIPRODUCT_AMD64="0F9709AE-0E5E-51AF-BCCD-A25314B4CE8B"
|
VERSION_MSIPRODUCT_AMD64="0F9709AE-0E5E-51AF-BCCD-A25314B4CE8B"
|
||||||
VERSION_MSIPRODUCT_ARM64="39D5D46E-E644-5C80-9EF8-224AC1AD5969"
|
VERSION_MSIPRODUCT_ARM64="39D5D46E-E644-5C80-9EF8-224AC1AD5969"
|
||||||
VERSION_MSIPRODUCT_X86="4487136B-2D11-5E42-BD80-B8529F3326F4"`},
|
VERSION_MSIPRODUCT_X86="4487136B-2D11-5E42-BD80-B8529F3326F4"`},
|
||||||
{mkInfo("abcdef", "defghi", corpDate, 1, 15, 0, 129), `
|
{mkInfo("abcdef", "defghi", otherDate, 1, 15, 0, 129), `
|
||||||
VERSION_SHORT="1.15.129"
|
VERSION_SHORT="1.15.129"
|
||||||
VERSION_LONG="1.15.129-tabcdef-gdefghi"
|
VERSION_LONG="1.15.129-tabcdef-gdefghi"
|
||||||
VERSION_GIT_HASH="abcdef"
|
VERSION_GIT_HASH="abcdef"
|
||||||
@ -105,7 +103,7 @@ func TestMkversion(t *testing.T) {
|
|||||||
VERSION_MSIPRODUCT_AMD64="89C96952-1FB8-5A4D-B02E-16A8060C56AA"
|
VERSION_MSIPRODUCT_AMD64="89C96952-1FB8-5A4D-B02E-16A8060C56AA"
|
||||||
VERSION_MSIPRODUCT_ARM64="DB1A2E86-66C4-5CEC-8F4C-7DB805370F3A"
|
VERSION_MSIPRODUCT_ARM64="DB1A2E86-66C4-5CEC-8F4C-7DB805370F3A"
|
||||||
VERSION_MSIPRODUCT_X86="DC57C0C3-5164-5C92-86B3-2800CEFF0540"`},
|
VERSION_MSIPRODUCT_X86="DC57C0C3-5164-5C92-86B3-2800CEFF0540"`},
|
||||||
{mkInfo("abcdef", "", corpDate, 1, 2, 0, 17), `
|
{mkInfo("abcdef", "", otherDate, 1, 2, 0, 17), `
|
||||||
VERSION_SHORT="1.2.0"
|
VERSION_SHORT="1.2.0"
|
||||||
VERSION_LONG="1.2.0-17-tabcdef"
|
VERSION_LONG="1.2.0-17-tabcdef"
|
||||||
VERSION_GIT_HASH="abcdef"
|
VERSION_GIT_HASH="abcdef"
|
||||||
@ -117,7 +115,7 @@ func TestMkversion(t *testing.T) {
|
|||||||
VERSION_MSIPRODUCT_AMD64="0F9709AE-0E5E-51AF-BCCD-A25314B4CE8B"
|
VERSION_MSIPRODUCT_AMD64="0F9709AE-0E5E-51AF-BCCD-A25314B4CE8B"
|
||||||
VERSION_MSIPRODUCT_ARM64="39D5D46E-E644-5C80-9EF8-224AC1AD5969"
|
VERSION_MSIPRODUCT_ARM64="39D5D46E-E644-5C80-9EF8-224AC1AD5969"
|
||||||
VERSION_MSIPRODUCT_X86="4487136B-2D11-5E42-BD80-B8529F3326F4"`},
|
VERSION_MSIPRODUCT_X86="4487136B-2D11-5E42-BD80-B8529F3326F4"`},
|
||||||
{mkInfo("abcdef", "defghi", corpDate, 1, 15, 0, 129), `
|
{mkInfo("abcdef", "defghi", otherDate, 1, 15, 0, 129), `
|
||||||
VERSION_SHORT="1.15.129"
|
VERSION_SHORT="1.15.129"
|
||||||
VERSION_LONG="1.15.129-tabcdef-gdefghi"
|
VERSION_LONG="1.15.129-tabcdef-gdefghi"
|
||||||
VERSION_GIT_HASH="abcdef"
|
VERSION_GIT_HASH="abcdef"
|
||||||
@ -129,9 +127,9 @@ func TestMkversion(t *testing.T) {
|
|||||||
VERSION_MSIPRODUCT_AMD64="89C96952-1FB8-5A4D-B02E-16A8060C56AA"
|
VERSION_MSIPRODUCT_AMD64="89C96952-1FB8-5A4D-B02E-16A8060C56AA"
|
||||||
VERSION_MSIPRODUCT_ARM64="DB1A2E86-66C4-5CEC-8F4C-7DB805370F3A"
|
VERSION_MSIPRODUCT_ARM64="DB1A2E86-66C4-5CEC-8F4C-7DB805370F3A"
|
||||||
VERSION_MSIPRODUCT_X86="DC57C0C3-5164-5C92-86B3-2800CEFF0540"`},
|
VERSION_MSIPRODUCT_X86="DC57C0C3-5164-5C92-86B3-2800CEFF0540"`},
|
||||||
{mkInfo("abcdef", "", corpDate, 0, 99, 5, 0), ""}, // unstable, patch number not allowed
|
{mkInfo("abcdef", "", otherDate, 0, 99, 5, 0), ""}, // unstable, patch number not allowed
|
||||||
{mkInfo("abcdef", "", corpDate, 0, 99, 5, 123), ""}, // unstable, patch number not allowed
|
{mkInfo("abcdef", "", otherDate, 0, 99, 5, 123), ""}, // unstable, patch number not allowed
|
||||||
{mkInfo("abcdef", "defghi", "", 1, 15, 0, 129), ""}, // missing corpDate
|
{mkInfo("abcdef", "defghi", "", 1, 15, 0, 129), ""}, // missing otherDate
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user