mirror of https://github.com/gogits/gogs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.6 KiB
159 lines
3.6 KiB
package version |
|
|
|
import ( |
|
"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: false |
|
func 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: true |
|
func 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: -1 |
|
func 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 |
|
}
|
|
|