master
go 75 lines 1.67 KB
Raw
1 package migrations
2
3 import (
4 "bufio"
5 "bytes"
6 "context"
7 "errors"
8 "fmt"
9 "path"
10 "sort"
11 "strings"
12
13 "github.com/blang/semver/v4"
14 )
15
16 const distVersions = "versions"
17
18 // LatestDistVersion returns the latest version, of the specified distribution,
19 // that is available on the distribution site.
20 func LatestDistVersion(ctx context.Context, fetcher Fetcher, dist string, stableOnly bool) (string, error) {
21 vs, err := DistVersions(ctx, fetcher, dist, false)
22 if err != nil {
23 return "", err
24 }
25
26 for i := len(vs) - 1; i >= 0; i-- {
27 ver := vs[i]
28 if stableOnly && strings.Contains(ver, "-rc") {
29 continue
30 }
31 if strings.Contains(ver, "-dev") {
32 continue
33 }
34 return ver, nil
35 }
36 return "", errors.New("could not find a non dev version")
37 }
38
39 // DistVersions returns all versions of the specified distribution, that are
40 // available on the distriburion site. List is in ascending order, unless
41 // sortDesc is true.
42 func DistVersions(ctx context.Context, fetcher Fetcher, dist string, sortDesc bool) ([]string, error) {
43 versionBytes, err := fetcher.Fetch(ctx, path.Join(dist, distVersions))
44 if err != nil {
45 return nil, err
46 }
47
48 prefix := "v"
49 var vers []semver.Version
50
51 scan := bufio.NewScanner(bytes.NewReader(versionBytes))
52 for scan.Scan() {
53 ver, err := semver.Make(strings.TrimLeft(scan.Text(), prefix))
54 if err != nil {
55 continue
56 }
57 vers = append(vers, ver)
58 }
59 if scan.Err() != nil {
60 return nil, fmt.Errorf("could not read versions: %w", scan.Err())
61 }
62
63 if sortDesc {
64 sort.Sort(sort.Reverse(semver.Versions(vers)))
65 } else {
66 sort.Sort(semver.Versions(vers))
67 }
68
69 out := make([]string, len(vers))
70 for i := range vers {
71 out[i] = prefix + vers[i].String()
72 }
73
74 return out, nil
75 }