-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathversion_checker.go
114 lines (97 loc) · 2.88 KB
/
version_checker.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
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
package core
import (
"errors"
"fmt"
"net/http"
"path"
"slices"
"strings"
"time"
"github.com/Masterminds/semver/v3"
)
const (
githubReleases = "https://github.com/MagaluCloud/mgccli/releases/latest"
updateInterval = 2 * time.Hour
versionLastCheck = "version_last_check"
)
type configValue func(key string, value interface{}) error
type getCall func(url string) (resp *http.Response, err error)
type VersionChecker struct {
getCall getCall
getConfig configValue
setConfig configValue
}
// NewVersionChecker creates a new VersionChecker
// getHttp - the getCall client to use for requests
// getConfig - a function to get a config value
// setConfig - a function to set a config value
func NewVersionChecker(
getHttp getCall, getConfig, setConfig configValue,
) *VersionChecker {
return &VersionChecker{getCall: getHttp, getConfig: getConfig, setConfig: setConfig}
}
// CheckVersion checks if the current version is outdated
// and prints a message if it is.
// It also sets the last check time to the current time.
// currentVersion - the current version of the cli
// args - optional command line arguments
func (v *VersionChecker) CheckVersion(currentVersion string, args ...string) {
logger().Debug("Checking for updates")
lastCheckTime := v.getLastCheckTime()
isVersionCmd := len(args) > 0 && slices.Contains(args, "--version")
if !isVersionCmd && time.Since(lastCheckTime) < updateInterval {
logger().Debug("Skipping update check")
return
}
latestVersion, err := v.getLatestVersion()
if err != nil {
logger().Debugw("cannot getConfig latest version", "err", err)
return
}
cv, err := semver.NewVersion(strings.SplitN(currentVersion, " ", 2)[0])
if err != nil {
fmt.Println("Invalid current version:", err)
return
}
latestSemVersion, err := semver.NewVersion(latestVersion)
if err != nil {
logger().Debugw("cannot parse latest version", "err", err)
return
}
if cv.LessThan(latestSemVersion) {
v.setCurrentTime()
fmt.Printf(
"⚠️ You are using an outdated version of mgc cli. "+
"Please update to the latest version: %s \n\n\n", latestVersion,
)
return
}
logger().Debug("No updates available")
v.setCurrentTime()
}
func (v *VersionChecker) getLastCheckTime() time.Time {
var lastCheck string
_ = v.getConfig(versionLastCheck, &lastCheck)
lastCheckTime, err := time.Parse(time.RFC3339, lastCheck)
if err != nil {
v.setCurrentTime()
}
return lastCheckTime
}
func (v *VersionChecker) getLatestVersion() (string, error) {
response, err := v.getCall(githubReleases)
if err != nil {
return "", err
}
location := response.Header.Get("Location")
if location == "" {
return "", errors.New("no location header")
}
return path.Base(location), nil
}
func (v *VersionChecker) setCurrentTime() {
err := v.setConfig(versionLastCheck, time.Now().Format(time.RFC3339))
if err != nil {
logger().Debugw("cannot set last check time", "err", err)
}
}