internal/gitutil/versions.go

v1.28.1
gitbay/internal/gitutil/versions.go history · blame · raw

50 lines · 1001 bytes

 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}