|
|
|
|
@ -5,7 +5,6 @@ |
|
|
|
|
package version |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"strconv" |
|
|
|
|
"strings" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
@ -68,8 +67,8 @@ type parsed struct { |
|
|
|
|
|
|
|
|
|
func parse(version string) (parsed, bool) { |
|
|
|
|
if strings.HasPrefix(version, "date.") { |
|
|
|
|
stamp, err := strconv.Atoi(version[5:]) |
|
|
|
|
if err != nil { |
|
|
|
|
stamp, ok := atoi(version[5:]) |
|
|
|
|
if !ok { |
|
|
|
|
return parsed{}, false |
|
|
|
|
} |
|
|
|
|
return parsed{Datestamp: stamp}, true |
|
|
|
|
@ -77,8 +76,8 @@ func parse(version string) (parsed, bool) { |
|
|
|
|
|
|
|
|
|
var ret parsed |
|
|
|
|
|
|
|
|
|
major, rest, err := splitNumericPrefix(version) |
|
|
|
|
if err != nil { |
|
|
|
|
major, rest, ok := splitNumericPrefix(version) |
|
|
|
|
if !ok { |
|
|
|
|
return parsed{}, false |
|
|
|
|
} |
|
|
|
|
ret.Major = major |
|
|
|
|
@ -86,8 +85,8 @@ func parse(version string) (parsed, bool) { |
|
|
|
|
return ret, true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret.Minor, rest, err = splitNumericPrefix(rest[1:]) |
|
|
|
|
if err != nil { |
|
|
|
|
ret.Minor, rest, ok = splitNumericPrefix(rest[1:]) |
|
|
|
|
if !ok { |
|
|
|
|
return parsed{}, false |
|
|
|
|
} |
|
|
|
|
if len(rest) == 0 { |
|
|
|
|
@ -96,8 +95,8 @@ func parse(version string) (parsed, bool) { |
|
|
|
|
|
|
|
|
|
// Optional patch version, if the next separator is a dot.
|
|
|
|
|
if rest[0] == '.' { |
|
|
|
|
ret.Patch, rest, err = splitNumericPrefix(rest[1:]) |
|
|
|
|
if err != nil { |
|
|
|
|
ret.Patch, rest, ok = splitNumericPrefix(rest[1:]) |
|
|
|
|
if !ok { |
|
|
|
|
return parsed{}, false |
|
|
|
|
} |
|
|
|
|
if len(rest) == 0 { |
|
|
|
|
@ -112,29 +111,84 @@ func parse(version string) (parsed, bool) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var trailer string |
|
|
|
|
ret.ExtraCommits, trailer, err = splitNumericPrefix(rest[1:]) |
|
|
|
|
if err != nil || (len(trailer) > 0 && trailer[0] != '-') { |
|
|
|
|
ret.ExtraCommits, trailer, ok = splitNumericPrefix(rest[1:]) |
|
|
|
|
if !ok || (len(trailer) > 0 && trailer[0] != '-') { |
|
|
|
|
// rest was probably the string trailer, ignore it.
|
|
|
|
|
ret.ExtraCommits = 0 |
|
|
|
|
} |
|
|
|
|
return ret, true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func splitNumericPrefix(s string) (int, string, error) { |
|
|
|
|
func splitNumericPrefix(s string) (n int, rest string, ok bool) { |
|
|
|
|
for i, r := range s { |
|
|
|
|
if r >= '0' && r <= '9' { |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
ret, err := strconv.Atoi(s[:i]) |
|
|
|
|
if err != nil { |
|
|
|
|
return 0, "", err |
|
|
|
|
ret, ok := atoi(s[:i]) |
|
|
|
|
if !ok { |
|
|
|
|
return 0, "", false |
|
|
|
|
} |
|
|
|
|
return ret, s[i:], true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret, ok := atoi(s) |
|
|
|
|
if !ok { |
|
|
|
|
return 0, "", false |
|
|
|
|
} |
|
|
|
|
return ret, "", true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
maxUint = ^uint(0) |
|
|
|
|
maxInt = int(maxUint >> 1) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// atoi parses an int from a string s.
|
|
|
|
|
// The bool result reports whether s is a number
|
|
|
|
|
// representable by a value of type int.
|
|
|
|
|
//
|
|
|
|
|
// From Go's runtime/string.go.
|
|
|
|
|
func atoi(s string) (int, bool) { |
|
|
|
|
if s == "" { |
|
|
|
|
return 0, false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
neg := false |
|
|
|
|
if s[0] == '-' { |
|
|
|
|
neg = true |
|
|
|
|
s = s[1:] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
un := uint(0) |
|
|
|
|
for i := 0; i < len(s); i++ { |
|
|
|
|
c := s[i] |
|
|
|
|
if c < '0' || c > '9' { |
|
|
|
|
return 0, false |
|
|
|
|
} |
|
|
|
|
if un > maxUint/10 { |
|
|
|
|
// overflow
|
|
|
|
|
return 0, false |
|
|
|
|
} |
|
|
|
|
return ret, s[i:], nil |
|
|
|
|
un *= 10 |
|
|
|
|
un1 := un + uint(c) - '0' |
|
|
|
|
if un1 < un { |
|
|
|
|
// overflow
|
|
|
|
|
return 0, false |
|
|
|
|
} |
|
|
|
|
un = un1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret, err := strconv.Atoi(s) |
|
|
|
|
if err != nil { |
|
|
|
|
return 0, "", err |
|
|
|
|
if !neg && un > uint(maxInt) { |
|
|
|
|
return 0, false |
|
|
|
|
} |
|
|
|
|
if neg && un > uint(maxInt)+1 { |
|
|
|
|
return 0, false |
|
|
|
|
} |
|
|
|
|
return ret, "", nil |
|
|
|
|
|
|
|
|
|
n := int(un) |
|
|
|
|
if neg { |
|
|
|
|
n = -n |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return n, true |
|
|
|
|
} |
|
|
|
|
|