Skip to content

Commit 9788b48

Browse files
committed
Improve latest version checking
1 parent 9f90755 commit 9788b48

File tree

3 files changed

+44
-36
lines changed

3 files changed

+44
-36
lines changed

internal/update/github.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
const githubRepo = "localstack/lstk"
1515

16-
var latestReleaseURL = "https://api.github.com/repos/" + githubRepo + "/releases/latest"
16+
const latestReleaseURL = "https://api.github.com/repos/" + githubRepo + "/releases/latest"
1717

1818
type githubRelease struct {
1919
TagName string `json:"tag_name"`

internal/update/notify.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,30 @@ package update
33
import (
44
"context"
55
"fmt"
6+
"time"
67

78
"github.com/localstack/lstk/internal/output"
89
"github.com/localstack/lstk/internal/version"
910
)
1011

12+
type versionFetcher func(ctx context.Context, token string) (string, error)
13+
14+
const checkTimeout = 500 * time.Millisecond
15+
1116
func CheckQuietly(ctx context.Context, githubToken string) (current, latest string, available bool) {
12-
return checkQuietlyWithVersion(ctx, githubToken, version.Version())
17+
return checkQuietlyWithVersion(ctx, githubToken, version.Version(), fetchLatestVersion)
1318
}
1419

15-
func checkQuietlyWithVersion(ctx context.Context, githubToken string, currentVersion string) (current, latest string, available bool) {
20+
func checkQuietlyWithVersion(ctx context.Context, githubToken string, currentVersion string, fetch versionFetcher) (current, latest string, available bool) {
1621
current = currentVersion
1722
if current == "dev" {
1823
return current, "", false
1924
}
2025

21-
latestVer, err := fetchLatestVersion(ctx, githubToken)
26+
ctx, cancel := context.WithTimeout(ctx, checkTimeout)
27+
defer cancel()
28+
29+
latestVer, err := fetch(ctx, githubToken)
2230
if err != nil {
2331
return current, "", false
2432
}
@@ -42,11 +50,11 @@ func UpdateCommandHint(info InstallInfo) string {
4250
}
4351

4452
func NotifyUpdate(ctx context.Context, sink output.Sink, githubToken string, updatePrompt bool, persistDisable func() error) (exitAfter bool) {
45-
return notifyUpdateWithVersion(ctx, sink, githubToken, updatePrompt, persistDisable, version.Version())
53+
return notifyUpdateWithVersion(ctx, sink, githubToken, updatePrompt, persistDisable, version.Version(), fetchLatestVersion)
4654
}
4755

48-
func notifyUpdateWithVersion(ctx context.Context, sink output.Sink, githubToken string, updatePrompt bool, persistDisable func() error, currentVersion string) (exitAfter bool) {
49-
current, latest, available := checkQuietlyWithVersion(ctx, githubToken, currentVersion)
56+
func notifyUpdateWithVersion(ctx context.Context, sink output.Sink, githubToken string, updatePrompt bool, persistDisable func() error, currentVersion string, fetch versionFetcher) (exitAfter bool) {
57+
current, latest, available := checkQuietlyWithVersion(ctx, githubToken, currentVersion, fetch)
5058
if !available {
5159
return false
5260
}

internal/update/notify_test.go

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package update
33
import (
44
"context"
55
"encoding/json"
6+
"fmt"
67
"net/http"
78
"net/http/httptest"
89
"testing"
@@ -22,11 +23,23 @@ func newTestGitHubServer(t *testing.T, tagName string) *httptest.Server {
2223
}))
2324
}
2425

25-
func withLatestReleaseURL(t *testing.T, url string) func() {
26-
t.Helper()
27-
orig := latestReleaseURL
28-
latestReleaseURL = url
29-
return func() { latestReleaseURL = orig }
26+
func testFetcher(serverURL string) versionFetcher {
27+
return func(ctx context.Context, token string) (string, error) {
28+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, serverURL, nil)
29+
if err != nil {
30+
return "", err
31+
}
32+
resp, err := http.DefaultClient.Do(req)
33+
if err != nil {
34+
return "", err
35+
}
36+
defer func() { _ = resp.Body.Close() }()
37+
var release githubRelease
38+
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
39+
return "", err
40+
}
41+
return release.TagName, nil
42+
}
3043
}
3144

3245
func TestCheckQuietlyDevBuild(t *testing.T) {
@@ -37,10 +50,11 @@ func TestCheckQuietlyDevBuild(t *testing.T) {
3750
}
3851

3952
func TestCheckQuietlyNetworkError(t *testing.T) {
40-
cleanup := withLatestReleaseURL(t, "http://localhost:1/nonexistent")
41-
defer cleanup()
53+
fetch := func(ctx context.Context, token string) (string, error) {
54+
return "", fmt.Errorf("connection refused")
55+
}
4256

43-
current, latest, available := checkQuietlyWithVersion(context.Background(), "", "1.0.0")
57+
current, latest, available := checkQuietlyWithVersion(context.Background(), "", "1.0.0", fetch)
4458
assert.Equal(t, "1.0.0", current)
4559
assert.Empty(t, latest)
4660
assert.False(t, available)
@@ -49,10 +63,8 @@ func TestCheckQuietlyNetworkError(t *testing.T) {
4963
func TestCheckQuietlyUpdateAvailable(t *testing.T) {
5064
server := newTestGitHubServer(t, "v2.0.0")
5165
defer server.Close()
52-
cleanup := withLatestReleaseURL(t, server.URL)
53-
defer cleanup()
5466

55-
current, latest, available := checkQuietlyWithVersion(context.Background(), "", "1.0.0")
67+
current, latest, available := checkQuietlyWithVersion(context.Background(), "", "1.0.0", testFetcher(server.URL))
5668
assert.Equal(t, "1.0.0", current)
5769
assert.Equal(t, "v2.0.0", latest)
5870
assert.True(t, available)
@@ -61,10 +73,8 @@ func TestCheckQuietlyUpdateAvailable(t *testing.T) {
6173
func TestCheckQuietlyAlreadyUpToDate(t *testing.T) {
6274
server := newTestGitHubServer(t, "v1.0.0")
6375
defer server.Close()
64-
cleanup := withLatestReleaseURL(t, server.URL)
65-
defer cleanup()
6676

67-
current, latest, available := checkQuietlyWithVersion(context.Background(), "", "v1.0.0")
77+
current, latest, available := checkQuietlyWithVersion(context.Background(), "", "v1.0.0", testFetcher(server.URL))
6878
assert.Equal(t, "v1.0.0", current)
6979
assert.Equal(t, "v1.0.0", latest)
7080
assert.False(t, available)
@@ -87,27 +97,23 @@ func TestUpdateCommandHint(t *testing.T) {
8797
func TestNotifyUpdateNoUpdateAvailable(t *testing.T) {
8898
server := newTestGitHubServer(t, "v1.0.0")
8999
defer server.Close()
90-
cleanup := withLatestReleaseURL(t, server.URL)
91-
defer cleanup()
92100

93101
var events []any
94102
sink := output.SinkFunc(func(event any) { events = append(events, event) })
95103

96-
exit := notifyUpdateWithVersion(context.Background(), sink, "", true, nil, "v1.0.0")
104+
exit := notifyUpdateWithVersion(context.Background(), sink, "", true, nil, "v1.0.0", testFetcher(server.URL))
97105
assert.False(t, exit)
98106
assert.Empty(t, events)
99107
}
100108

101109
func TestNotifyUpdatePromptDisabled(t *testing.T) {
102110
server := newTestGitHubServer(t, "v2.0.0")
103111
defer server.Close()
104-
cleanup := withLatestReleaseURL(t, server.URL)
105-
defer cleanup()
106112

107113
var events []any
108114
sink := output.SinkFunc(func(event any) { events = append(events, event) })
109115

110-
exit := notifyUpdateWithVersion(context.Background(), sink, "", false, nil, "1.0.0")
116+
exit := notifyUpdateWithVersion(context.Background(), sink, "", false, nil, "1.0.0", testFetcher(server.URL))
111117
assert.False(t, exit)
112118
assert.Len(t, events, 1)
113119
msg, ok := events[0].(output.MessageEvent)
@@ -119,8 +125,6 @@ func TestNotifyUpdatePromptDisabled(t *testing.T) {
119125
func TestNotifyUpdatePromptSkip(t *testing.T) {
120126
server := newTestGitHubServer(t, "v2.0.0")
121127
defer server.Close()
122-
cleanup := withLatestReleaseURL(t, server.URL)
123-
defer cleanup()
124128

125129
var events []any
126130
sink := output.SinkFunc(func(event any) {
@@ -130,15 +134,13 @@ func TestNotifyUpdatePromptSkip(t *testing.T) {
130134
}
131135
})
132136

133-
exit := notifyUpdateWithVersion(context.Background(), sink, "", true, nil, "1.0.0")
137+
exit := notifyUpdateWithVersion(context.Background(), sink, "", true, nil, "1.0.0", testFetcher(server.URL))
134138
assert.False(t, exit)
135139
}
136140

137141
func TestNotifyUpdatePromptNever(t *testing.T) {
138142
server := newTestGitHubServer(t, "v2.0.0")
139143
defer server.Close()
140-
cleanup := withLatestReleaseURL(t, server.URL)
141-
defer cleanup()
142144

143145
persistCalled := false
144146

@@ -153,16 +155,14 @@ func TestNotifyUpdatePromptNever(t *testing.T) {
153155
exit := notifyUpdateWithVersion(context.Background(), sink, "", true, func() error {
154156
persistCalled = true
155157
return nil
156-
}, "1.0.0")
158+
}, "1.0.0", testFetcher(server.URL))
157159
assert.False(t, exit)
158160
assert.True(t, persistCalled)
159161
}
160162

161163
func TestNotifyUpdatePromptCancelled(t *testing.T) {
162164
server := newTestGitHubServer(t, "v2.0.0")
163165
defer server.Close()
164-
cleanup := withLatestReleaseURL(t, server.URL)
165-
defer cleanup()
166166

167167
var events []any
168168
sink := output.SinkFunc(func(event any) {
@@ -172,6 +172,6 @@ func TestNotifyUpdatePromptCancelled(t *testing.T) {
172172
}
173173
})
174174

175-
exit := notifyUpdateWithVersion(context.Background(), sink, "", true, nil, "1.0.0")
175+
exit := notifyUpdateWithVersion(context.Background(), sink, "", true, nil, "1.0.0", testFetcher(server.URL))
176176
assert.False(t, exit)
177177
}

0 commit comments

Comments
 (0)