Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / mod@v0.3.0 / semver / semver.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package semver implements comparison of semantic version strings.
6 // In this package, semantic version strings must begin with a leading "v",
7 // as in "v1.0.0".
8 //
9 // The general form of a semantic version string accepted by this package is
10 //
11 //      vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]
12 //
13 // where square brackets indicate optional parts of the syntax;
14 // MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;
15 // PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers
16 // using only alphanumeric characters and hyphens; and
17 // all-numeric PRERELEASE identifiers must not have leading zeros.
18 //
19 // This package follows Semantic Versioning 2.0.0 (see semver.org)
20 // with two exceptions. First, it requires the "v" prefix. Second, it recognizes
21 // vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
22 // as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
23 package semver
24
25 // parsed returns the parsed form of a semantic version string.
26 type parsed struct {
27         major      string
28         minor      string
29         patch      string
30         short      string
31         prerelease string
32         build      string
33         err        string
34 }
35
36 // IsValid reports whether v is a valid semantic version string.
37 func IsValid(v string) bool {
38         _, ok := parse(v)
39         return ok
40 }
41
42 // Canonical returns the canonical formatting of the semantic version v.
43 // It fills in any missing .MINOR or .PATCH and discards build metadata.
44 // Two semantic versions compare equal only if their canonical formattings
45 // are identical strings.
46 // The canonical invalid semantic version is the empty string.
47 func Canonical(v string) string {
48         p, ok := parse(v)
49         if !ok {
50                 return ""
51         }
52         if p.build != "" {
53                 return v[:len(v)-len(p.build)]
54         }
55         if p.short != "" {
56                 return v + p.short
57         }
58         return v
59 }
60
61 // Major returns the major version prefix of the semantic version v.
62 // For example, Major("v2.1.0") == "v2".
63 // If v is an invalid semantic version string, Major returns the empty string.
64 func Major(v string) string {
65         pv, ok := parse(v)
66         if !ok {
67                 return ""
68         }
69         return v[:1+len(pv.major)]
70 }
71
72 // MajorMinor returns the major.minor version prefix of the semantic version v.
73 // For example, MajorMinor("v2.1.0") == "v2.1".
74 // If v is an invalid semantic version string, MajorMinor returns the empty string.
75 func MajorMinor(v string) string {
76         pv, ok := parse(v)
77         if !ok {
78                 return ""
79         }
80         i := 1 + len(pv.major)
81         if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {
82                 return v[:j]
83         }
84         return v[:i] + "." + pv.minor
85 }
86
87 // Prerelease returns the prerelease suffix of the semantic version v.
88 // For example, Prerelease("v2.1.0-pre+meta") == "-pre".
89 // If v is an invalid semantic version string, Prerelease returns the empty string.
90 func Prerelease(v string) string {
91         pv, ok := parse(v)
92         if !ok {
93                 return ""
94         }
95         return pv.prerelease
96 }
97
98 // Build returns the build suffix of the semantic version v.
99 // For example, Build("v2.1.0+meta") == "+meta".
100 // If v is an invalid semantic version string, Build returns the empty string.
101 func Build(v string) string {
102         pv, ok := parse(v)
103         if !ok {
104                 return ""
105         }
106         return pv.build
107 }
108
109 // Compare returns an integer comparing two versions according to
110 // semantic version precedence.
111 // The result will be 0 if v == w, -1 if v < w, or +1 if v > w.
112 //
113 // An invalid semantic version string is considered less than a valid one.
114 // All invalid semantic version strings compare equal to each other.
115 func Compare(v, w string) int {
116         pv, ok1 := parse(v)
117         pw, ok2 := parse(w)
118         if !ok1 && !ok2 {
119                 return 0
120         }
121         if !ok1 {
122                 return -1
123         }
124         if !ok2 {
125                 return +1
126         }
127         if c := compareInt(pv.major, pw.major); c != 0 {
128                 return c
129         }
130         if c := compareInt(pv.minor, pw.minor); c != 0 {
131                 return c
132         }
133         if c := compareInt(pv.patch, pw.patch); c != 0 {
134                 return c
135         }
136         return comparePrerelease(pv.prerelease, pw.prerelease)
137 }
138
139 // Max canonicalizes its arguments and then returns the version string
140 // that compares greater.
141 func Max(v, w string) string {
142         v = Canonical(v)
143         w = Canonical(w)
144         if Compare(v, w) > 0 {
145                 return v
146         }
147         return w
148 }
149
150 func parse(v string) (p parsed, ok bool) {
151         if v == "" || v[0] != 'v' {
152                 p.err = "missing v prefix"
153                 return
154         }
155         p.major, v, ok = parseInt(v[1:])
156         if !ok {
157                 p.err = "bad major version"
158                 return
159         }
160         if v == "" {
161                 p.minor = "0"
162                 p.patch = "0"
163                 p.short = ".0.0"
164                 return
165         }
166         if v[0] != '.' {
167                 p.err = "bad minor prefix"
168                 ok = false
169                 return
170         }
171         p.minor, v, ok = parseInt(v[1:])
172         if !ok {
173                 p.err = "bad minor version"
174                 return
175         }
176         if v == "" {
177                 p.patch = "0"
178                 p.short = ".0"
179                 return
180         }
181         if v[0] != '.' {
182                 p.err = "bad patch prefix"
183                 ok = false
184                 return
185         }
186         p.patch, v, ok = parseInt(v[1:])
187         if !ok {
188                 p.err = "bad patch version"
189                 return
190         }
191         if len(v) > 0 && v[0] == '-' {
192                 p.prerelease, v, ok = parsePrerelease(v)
193                 if !ok {
194                         p.err = "bad prerelease"
195                         return
196                 }
197         }
198         if len(v) > 0 && v[0] == '+' {
199                 p.build, v, ok = parseBuild(v)
200                 if !ok {
201                         p.err = "bad build"
202                         return
203                 }
204         }
205         if v != "" {
206                 p.err = "junk on end"
207                 ok = false
208                 return
209         }
210         ok = true
211         return
212 }
213
214 func parseInt(v string) (t, rest string, ok bool) {
215         if v == "" {
216                 return
217         }
218         if v[0] < '0' || '9' < v[0] {
219                 return
220         }
221         i := 1
222         for i < len(v) && '0' <= v[i] && v[i] <= '9' {
223                 i++
224         }
225         if v[0] == '0' && i != 1 {
226                 return
227         }
228         return v[:i], v[i:], true
229 }
230
231 func parsePrerelease(v string) (t, rest string, ok bool) {
232         // "A pre-release version MAY be denoted by appending a hyphen and
233         // a series of dot separated identifiers immediately following the patch version.
234         // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
235         // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes."
236         if v == "" || v[0] != '-' {
237                 return
238         }
239         i := 1
240         start := 1
241         for i < len(v) && v[i] != '+' {
242                 if !isIdentChar(v[i]) && v[i] != '.' {
243                         return
244                 }
245                 if v[i] == '.' {
246                         if start == i || isBadNum(v[start:i]) {
247                                 return
248                         }
249                         start = i + 1
250                 }
251                 i++
252         }
253         if start == i || isBadNum(v[start:i]) {
254                 return
255         }
256         return v[:i], v[i:], true
257 }
258
259 func parseBuild(v string) (t, rest string, ok bool) {
260         if v == "" || v[0] != '+' {
261                 return
262         }
263         i := 1
264         start := 1
265         for i < len(v) {
266                 if !isIdentChar(v[i]) && v[i] != '.' {
267                         return
268                 }
269                 if v[i] == '.' {
270                         if start == i {
271                                 return
272                         }
273                         start = i + 1
274                 }
275                 i++
276         }
277         if start == i {
278                 return
279         }
280         return v[:i], v[i:], true
281 }
282
283 func isIdentChar(c byte) bool {
284         return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'
285 }
286
287 func isBadNum(v string) bool {
288         i := 0
289         for i < len(v) && '0' <= v[i] && v[i] <= '9' {
290                 i++
291         }
292         return i == len(v) && i > 1 && v[0] == '0'
293 }
294
295 func isNum(v string) bool {
296         i := 0
297         for i < len(v) && '0' <= v[i] && v[i] <= '9' {
298                 i++
299         }
300         return i == len(v)
301 }
302
303 func compareInt(x, y string) int {
304         if x == y {
305                 return 0
306         }
307         if len(x) < len(y) {
308                 return -1
309         }
310         if len(x) > len(y) {
311                 return +1
312         }
313         if x < y {
314                 return -1
315         } else {
316                 return +1
317         }
318 }
319
320 func comparePrerelease(x, y string) int {
321         // "When major, minor, and patch are equal, a pre-release version has
322         // lower precedence than a normal version.
323         // Example: 1.0.0-alpha < 1.0.0.
324         // Precedence for two pre-release versions with the same major, minor,
325         // and patch version MUST be determined by comparing each dot separated
326         // identifier from left to right until a difference is found as follows:
327         // identifiers consisting of only digits are compared numerically and
328         // identifiers with letters or hyphens are compared lexically in ASCII
329         // sort order. Numeric identifiers always have lower precedence than
330         // non-numeric identifiers. A larger set of pre-release fields has a
331         // higher precedence than a smaller set, if all of the preceding
332         // identifiers are equal.
333         // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <
334         // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0."
335         if x == y {
336                 return 0
337         }
338         if x == "" {
339                 return +1
340         }
341         if y == "" {
342                 return -1
343         }
344         for x != "" && y != "" {
345                 x = x[1:] // skip - or .
346                 y = y[1:] // skip - or .
347                 var dx, dy string
348                 dx, x = nextIdent(x)
349                 dy, y = nextIdent(y)
350                 if dx != dy {
351                         ix := isNum(dx)
352                         iy := isNum(dy)
353                         if ix != iy {
354                                 if ix {
355                                         return -1
356                                 } else {
357                                         return +1
358                                 }
359                         }
360                         if ix {
361                                 if len(dx) < len(dy) {
362                                         return -1
363                                 }
364                                 if len(dx) > len(dy) {
365                                         return +1
366                                 }
367                         }
368                         if dx < dy {
369                                 return -1
370                         } else {
371                                 return +1
372                         }
373                 }
374         }
375         if x == "" {
376                 return -1
377         } else {
378                 return +1
379         }
380 }
381
382 func nextIdent(x string) (dx, rest string) {
383         i := 0
384         for i < len(x) && x[i] != '.' {
385                 i++
386         }
387         return x[:i], x[i:]
388 }