-
Notifications
You must be signed in to change notification settings - Fork 5
/
version.go
82 lines (70 loc) · 2.02 KB
/
version.go
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
package version
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"golang.org/x/mod/semver"
)
const repoOwner = "bootdotdev"
const repoName = "bootdev"
type VersionInfo struct {
CurrentVersion string
LatestVersion string
IsOutdated bool
IsUpdateRequired bool
FailedToFetch error
}
func FetchUpdateInfo(currentVersion string) VersionInfo {
latest, err := getLatestVersion()
if err != nil {
return VersionInfo{
FailedToFetch: err,
}
}
isUpdateRequired := isUpdateRequired(currentVersion, latest)
isOutdated := isOutdated(currentVersion, latest)
return VersionInfo{
IsUpdateRequired: isUpdateRequired,
IsOutdated: isOutdated,
CurrentVersion: currentVersion,
LatestVersion: latest,
}
}
func (v *VersionInfo) PromptUpdateIfAvailable() {
if v.IsOutdated {
fmt.Fprintln(os.Stderr, "A new version of the bootdev CLI is available!")
fmt.Fprintln(os.Stderr, "Please run the following command to update:")
fmt.Fprintf(os.Stderr, " go install github.com/%s/%s@latest\n\n", repoOwner, repoName)
}
}
// Returns true if the current version is older than the latest.
func isOutdated(current string, latest string) bool {
return semver.Compare(current, latest) < 0
}
// Returns true if the latest version has a higher major or minor
// number than the current version. If you don't want to force
// an update, you can increment the patch number instead.
func isUpdateRequired(current string, latest string) bool {
latestMajorMinor := semver.MajorMinor(latest)
currentMajorMinor := semver.MajorMinor(current)
return semver.Compare(currentMajorMinor, latestMajorMinor) < 0
}
func getLatestVersion() (string, error) {
resp, err := http.Get(fmt.Sprintf("https://proxy.golang.org/github.com/%s/%s/@latest", repoOwner, repoName))
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
var version struct{ Version string }
err = json.Unmarshal(body, &version)
if err != nil {
return "", err
}
return version.Version, nil
}