gotest/version/version.go

106 lines
2.4 KiB
Go

package version
import (
"fmt"
"regexp"
"strconv"
"strings"
)
// Info : data structure for program version information
type Info struct {
Major int
Minor int
Patch int
Prerelease []string
BuildInfo []string
}
// Equal compares two Info structs for equality
func (i Info) Equal(o Info) bool {
if i.Major != o.Major || i.Minor != o.Minor || i.Patch != o.Patch {
return false
}
if len(i.Prerelease) != len(o.Prerelease) || len(i.BuildInfo) != len(o.BuildInfo) {
return false
}
for j := 0; j < len(i.Prerelease); j++ {
if i.Prerelease[j] != o.Prerelease[j] {
return false
}
}
for j := 0; j < len(i.BuildInfo); j++ {
if i.BuildInfo[j] != o.BuildInfo[j] {
return false
}
}
return true
}
// String returns a human friendly version string
func (i Info) String() string {
var b strings.Builder
fmt.Fprintf(&b, "v%d.%d.%d", i.Major, i.Minor, i.Patch)
if len(i.Prerelease) > 0 {
fmt.Fprintf(&b, "-%s", strings.Join(i.Prerelease, "."))
}
if len(i.BuildInfo) > 0 {
fmt.Fprintf(&b, "+%s", strings.Join(i.BuildInfo, "."))
}
return b.String()
}
/* reStr is a regular expression string to parse the output of git describe
Match groups:
1. version number (without "v")
2. major version
3. minor version
4. patch version
5. prerelease identifier
6. commit count
7. git short hash
8. "-dirty" if dirty, else ""
*/
const reStr = `^(?:v(([0-9]+)(?:\.([0-9]+)(?:\.([0-9]+))?)?))?(?:-((?:alpha|beta|rc|dev)(?:\.[a-zA-Z0-9]+)*))?(?:-([0-9]+)-g)?([a-f0-9A-F]+)?(?:(-dirty))?$`
var re = regexp.MustCompile(reStr)
func parseGitDescribe(input string) Info {
matches := re.FindStringSubmatch(input)
if matches == nil || matches[0] == "" {
return Info{0, 0, 0, []string{"dev"}, []string{"unknown"}}
}
info := Info{}
if matches[2] != "" {
num, _ := strconv.Atoi(matches[2])
info.Major = num
}
if matches[3] != "" {
num, _ := strconv.Atoi(matches[3])
info.Minor = num
}
if matches[4] != "" {
num, _ := strconv.Atoi(matches[4])
info.Patch = num
}
if matches[5] != "" {
info.Prerelease = strings.Split(matches[5], ".")
}
if matches[6] != "" || matches[7] != "" || matches[8] != "" {
info.BuildInfo = append(info.BuildInfo, "git")
if matches[6] != "" {
info.BuildInfo = append(info.BuildInfo, matches[6])
}
if matches[7] != "" {
info.BuildInfo = append(info.BuildInfo, matches[7])
}
if matches[8] != "" {
info.BuildInfo = append(info.BuildInfo, "dirty")
}
}
return info
}