internal/gitutil/versions.go
50 lines · 1001 bytes
3 symbols in this file
1package gitutil
2
3import (
4 "sort"
5 "strconv"
6 "strings"
7)
8
9// version parses "v1.2.3" or "1.2" into numeric parts. Anything else is
10// not a version.
11func version(name string) ([]int, bool) {
12 s := strings.TrimPrefix(name, "v")
13 if s == "" {
14 return nil, false
15 }
16 var parts []int
17 for _, p := range strings.Split(s, ".") {
18 n, err := strconv.Atoi(p)
19 if err != nil || n < 0 {
20 return nil, false
21 }
22 parts = append(parts, n)
23 }
24 return parts, true
25}
26
27func versionLess(a, b []int) bool {
28 for i := 0; i < len(a) && i < len(b); i++ {
29 if a[i] != b[i] {
30 return a[i] < b[i]
31 }
32 }
33 return len(a) < len(b)
34}
35
36// SortVersions orders refs newest version first. Names that are not
37// versions follow, by name.
38func SortVersions(refs []Ref) {
39 sort.SliceStable(refs, func(i, j int) bool {
40 vi, oki := version(refs[i].Name)
41 vj, okj := version(refs[j].Name)
42 switch {
43 case oki && okj:
44 return versionLess(vj, vi)
45 case oki != okj:
46 return oki
47 }
48 return refs[i].Name < refs[j].Name
49 })
50}