| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 | package versionimport (	"regexp"	"strconv"	"strings")var regexpSigns = regexp.MustCompile(`[_\-+]`)var regexpDotBeforeDigit = regexp.MustCompile(`([^.\d]+)`)var regexpMultipleDots = regexp.MustCompile(`\.{2,}`)var specialForms = map[string]int{	"dev":   -6,	"alpha": -5,	"a":     -5,	"beta":  -4,	"b":     -4,	"RC":    -3,	"rc":    -3,	"#":     -2,	"p":     1,	"pl":    1,}// Compares two version number strings, for a particular relationship//// Usage//     version.Compare("2.3.4", "v3.1.2", "<")//     Returns: true////     version.Compare("1.0rc1", "1.0", ">=")//     Returns: falsefunc Compare(version1, version2, operator string) bool {	version1N := Normalize(version1)	version2N := Normalize(version2)	return CompareNormalized(version1N, version2N, operator)}// Compares two normalizated version number strings, for a particular relationship//// The function first replaces _, - and + with a dot . in the version strings// and also inserts dots . before and after any non number so that for example// '4.3.2RC1' becomes '4.3.2.RC.1'.//// Then it splits the results like if you were using Split(version, '.').// Then it compares the parts starting from left to right. If a part contains// special version strings these are handled in the following order: any string// not found in this list://   < dev < alpha = a < beta = b < RC = rc < # < pl = p.//// Usage//     version.CompareNormalized("1.0-dev", "1.0", "<")//     Returns: true////     version.CompareNormalized("1.0rc1", "1.0", ">=")//     Returns: false////     version.CompareNormalized("1.0", "1.0b1", "ge")//     Returns: truefunc CompareNormalized(version1, version2, operator string) bool {	compare := CompareSimple(version1, version2)	switch {	case operator == ">" || operator == "gt":		return compare > 0	case operator == ">=" || operator == "ge":		return compare >= 0	case operator == "<=" || operator == "le":		return compare <= 0	case operator == "==" || operator == "=" || operator == "eq":		return compare == 0	case operator == "<>" || operator == "!=" || operator == "ne":		return compare != 0	case operator == "" || operator == "<" || operator == "lt":		return compare < 0	}	return false}// Compares two normalizated version number strings//// Just the same of CompareVersion but return a int result, 0 if both version// are equal, 1 if the right side is bigger and -1 if the right side is lower//// Usage//     version.CompareSimple("1.2", "1.0.1")//     Returns: 1////     version.CompareSimple("1.0rc1", "1.0")//     Returns: -1func CompareSimple(version1, version2 string) int {	var x, r, l int = 0, 0, 0	v1, v2 := prepVersion(version1), prepVersion(version2)	len1, len2 := len(v1), len(v2)	if len1 > len2 {		x = len1	} else {		x = len2	}	for i := 0; i < x; i++ {		if i < len1 && i < len2 {			if v1[i] == v2[i] {				continue			}		}		r = 0		if i < len1 {			r = numVersion(v1[i])		}		l = 0		if i < len2 {			l = numVersion(v2[i])		}		if r < l {			return -1		} else if r > l {			return 1		}	}	return 0}func prepVersion(version string) []string {	if len(version) == 0 {		return []string{""}	}	version = regexpSigns.ReplaceAllString(version, ".")	version = regexpDotBeforeDigit.ReplaceAllString(version, ".$1.")	version = regexpMultipleDots.ReplaceAllString(version, ".")	return strings.Split(version, ".")}func numVersion(value string) int {	if value == "" {		return 0	}	if number, err := strconv.Atoi(value); err == nil {		return number	}	if special, ok := specialForms[value]; ok {		return special	}	return -7}
 |