-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathversion.go
More file actions
181 lines (166 loc) · 4.1 KB
/
version.go
File metadata and controls
181 lines (166 loc) · 4.1 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package govm
import (
"encoding/json"
"fmt"
"github.com/pelletier/go-toml/v2"
"net/url"
"os"
"path/filepath"
"runtime"
"slices"
)
const (
storeFile = "store.toml"
)
type Store struct {
Versions map[string]Version `toml:"store"`
}
func ReadStore() (*Store, error) {
store, err := GetInstallation()
if err != nil {
return nil, err
}
storeFile, err := OpenFile(filepath.Join(store, storeFile), os.O_CREATE|os.O_RDWR, 0755)
if err != nil {
return nil, err
}
defer storeFile.Close()
var storeData Store
err = toml.NewDecoder(storeFile).Decode(&storeData)
if err != nil {
return nil, err
}
// initialize
if storeData.Versions == nil {
storeData.Versions = make(map[string]Version)
}
return &storeData, nil
}
func WriteStore(storeData *Store) error {
store, err := GetInstallation()
if err != nil {
return err
}
storeFile, err := OpenFile(filepath.Join(store, storeFile), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0755)
if err != nil {
return err
}
defer storeFile.Close()
return toml.NewEncoder(storeFile).Encode(storeData)
}
type GoVersion struct {
Version string `json:"version"`
Stable bool `json:"stable"`
Files []Version `json:"files"`
}
type Version struct {
Filename string `toml:"filename" json:"filename"`
Os string `toml:"os" json:"os"`
Arch string `toml:"arch" json:"arch"`
Version string `toml:"version" json:"version"`
Sha256 string `toml:"sha256" json:"sha256"`
Size uint64 `toml:"size" json:"size"`
Kind string `toml:"kind" json:"kind"`
Path string `toml:"path"`
Using bool `toml:"-"`
Stable bool `toml:"-"`
}
// GetRemoteVersion returns all available go versions from versionURL without git.
// If unstable is false, it only returns stable versions, otherwise it returns all versions that includes unstable versions.
func GetRemoteVersion(ascend, unstable bool) ([]Version, error) {
versionURL, err := GetVersionListAPI()
if err != nil {
return nil, err
}
httpClient, err := GetHttpClient()
if err != nil {
return nil, err
}
// get all versions from versionURL
response, err := httpClient.Get(versionURL)
if err != nil {
return nil, err
}
var versions []GoVersion
err = json.NewDecoder(response.Body).Decode(&versions)
if err != nil {
return nil, err
}
// filter by current os and arch
var filterVersions []Version
for _, goversion := range versions {
if !unstable && !goversion.Stable {
continue
}
for _, version := range goversion.Files {
if version.Kind == "archive" &&
version.Os == runtime.GOOS &&
version.Arch == runtime.GOARCH {
version.Stable = goversion.Stable
filterVersions = append(filterVersions, version)
}
}
}
// sort by version
slices.SortFunc(filterVersions, func(v1, v2 Version) int {
if ascend {
return CompareVersion(v1.Version, v2.Version)
}
return -CompareVersion(v1.Version, v2.Version)
})
return filterVersions, nil
}
func ChooseDownloadURL(version string) (string, string, error) {
source, err := GetMirror()
if err != nil {
return "", "", err
}
// the os and arch is same as current tool
os := runtime.GOOS
arch := runtime.GOARCH
var ext string
if os == "windows" {
ext = "zip"
} else {
ext = "tar.gz"
}
filename := fmt.Sprintf("%s.%s-%s.%s", version, os, arch, ext)
dlurl, err := url.JoinPath(source, filename)
if err != nil {
return "", "", err
}
return dlurl, filename, err
}
// GetLocalVersions returns the local versions from store.
func GetLocalVersions(ascend bool) ([]Version, error) {
storeData, err := ReadStore()
if err != nil {
return nil, err
}
usingVersion, err := GetUsingVersion()
if err != nil {
return nil, err
}
var localList []Version
for _, v := range storeData.Versions {
if usingVersion == v.Version {
v.Using = true
}
localList = append(localList, v)
}
slices.SortFunc(localList, func(v1, v2 Version) int {
if ascend {
return CompareVersion(v1.Version, v2.Version)
}
return -CompareVersion(v1.Version, v2.Version)
})
return localList, nil
}
func AppendVersion(v Version) error {
store, err := ReadStore()
if err != nil {
return err
}
store.Versions[v.Version] = v
return WriteStore(store)
}