package vaversion import ( "encoding/json" "errors" "flag" "fmt" "math" "os" "strconv" "strings" ) type ( VaVersion int64 ) var ( BuildVersion string BuildTime string CommitSha1 string AppName string ) func init() { var showVer bool flag.BoolVar(&showVer, "vbasic", false, "display build version") flag.Parse() if showVer { info := make(map[string]interface{}) info["version"] = BuildVersion info["build"] = BuildTime info["commit"] = CommitSha1 info["name"] = AppName b, err := json.Marshal(info) if nil != err { fmt.Println("internal error:", err) os.Exit(1) } else { fmt.Println(string(b)) os.Exit(0) } } } func (v VaVersion) Valid() bool { if v < 0 { return false } majorVersion := v >> 32 if majorVersion > math.MaxUint16 { return false } return true } func (v VaVersion) Compare(v1 VaVersion) (int, error) { if !v.Valid() { return 0, errors.New("Invalid VaVersion left value") } if !v1.Valid() { return 0, errors.New("Invalid VaVersion right value") } if v > v1 { return 1, nil } if v < v1 { return -1, nil } return 0, nil } func (v VaVersion) String() (string, error) { if !v.Valid() { return "", errors.New("Invalid VaVersion value") } majorVersion := (v >> 32) & 0xffff minorVersion := (v >> 16) & 0xffff buildNumber := v & 0xffff name := fmt.Sprintf("%d.%d.%d", majorVersion, minorVersion, buildNumber) return name, nil } func VersionName2VaVersion(version string) (VaVersion, error) { subVersions := strings.Split(version, ".") if len(subVersions) != 3 { return 0, errors.New("Incorrect version format, version formats like 1.12.3") } majorVersion, err := strconv.ParseInt(subVersions[0], 10, 64) if nil != err { return 0, errors.New(version + " major part can't be parsed, version formats like 1.12.3") } minorVersion, err := strconv.ParseInt(subVersions[1], 10, 64) if nil != err { return 0, errors.New(version + " minor part can't be parsed, version formats like 1.12.3") } buildNumber, err := strconv.ParseInt(subVersions[2], 10, 64) if nil != err { return 0, errors.New(version + " build number part can't be parsed, version formats like 1.12.3") } if majorVersion > math.MaxUint16 { return 0, errors.New(version + " major version too large, max value is:" + strconv.Itoa(math.MaxUint16)) } if minorVersion > math.MaxUint16 { return 0, errors.New(version + " minor version too large, max value is:" + strconv.Itoa(math.MaxUint16)) } if buildNumber > math.MaxUint16 { return 0, errors.New(version + " build number too large, max value is:" + strconv.Itoa(math.MaxUint16)) } num := (majorVersion << 32) | (minorVersion << 16) | buildNumber return VaVersion(num), nil }