forked from niemeyer/gopkg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathversion.go
110 lines (99 loc) · 2.11 KB
/
version.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"fmt"
)
type Version struct {
Major, Minor, Patch int
}
func (v Version) String() string {
if v.Major < 0 {
panic(fmt.Sprintf("cannot stringify invalid version (major is %d)", v.Major))
}
if v.Minor < 0 {
return fmt.Sprintf("v%d", v.Major)
}
if v.Patch < 0 {
return fmt.Sprintf("v%d.%d", v.Major, v.Minor)
}
return fmt.Sprintf("v%d.%d.%d", v.Major, v.Minor, v.Patch)
}
func (v Version) Less(other Version) bool {
if v.Major != other.Major {
return v.Major < other.Major
}
if v.Minor != other.Minor {
return v.Minor < other.Minor
}
return v.Patch < other.Patch
}
func (v Version) Contains(other Version) bool {
if v.Patch != -1 {
return v == other
}
if v.Minor != -1 {
return v.Major == other.Major && v.Minor == other.Minor
}
return v.Major == other.Major
}
func (v Version) IsValid() bool {
return v == InvalidVersion
}
var InvalidVersion = Version{-1, -1, -1}
func parseVersion(s string) (Version, bool) {
if len(s) < 2 {
return InvalidVersion, false
}
if s[0] != 'v' {
return InvalidVersion, false
}
v := Version{-1, -1, -1}
i := 1
v.Major, i = parseVersionPart(s, i)
if i < 0 {
return InvalidVersion, false
}
if i == len(s) {
return v, true
}
v.Minor, i = parseVersionPart(s, i)
if i < 0 {
return InvalidVersion, false
}
if i == len(s) {
return v, true
}
v.Patch, i = parseVersionPart(s, i)
if i < 0 || i < len(s) {
return InvalidVersion, false
}
return v, true
}
func parseVersionPart(s string, i int) (part int, newi int) {
dot := i
for dot < len(s) && s[dot] != '.' {
dot++
}
if dot == i || dot-i > 1 && s[i] == '0' {
return -1, -1
}
for i < len(s) {
if s[i] < '0' || s[i] > '9' {
return -1, -1
}
part *= 10
part += int(s[i] - '0')
if part < 0 {
return -1, -1
}
i++
if i+1 < len(s) && s[i] == '.' {
return part, i + 1
}
}
return part, i
}
// VersionList implements sort.Interface
type VersionList []Version
func (vl VersionList) Len() int { return len(vl) }
func (vl VersionList) Less(i, j int) bool { return vl[i].Less(vl[j]) }
func (vl VersionList) Swap(i, j int) { vl[i], vl[j] = vl[j], vl[i] }