Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit dcfeec1

Browse files
committed
internal/cmd/update.go: replace semver library
1 parent dabd178 commit dcfeec1

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.14
55
require (
66
cdr.dev/slog v1.4.1
77
cdr.dev/wsep v0.0.0-20200728013649-82316a09813f
8-
github.com/blang/semver/v4 v4.0.0
8+
github.com/Masterminds/semver/v3 v3.1.1
99
github.com/briandowns/spinner v1.16.0
1010
github.com/cli/safeexec v1.0.0
1111
github.com/fatih/color v1.12.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
4949
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
5050
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
5151
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
52+
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
53+
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
5254
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
5355
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
5456
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
@@ -69,8 +71,6 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
6971
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
7072
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
7173
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
72-
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
73-
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
7474
github.com/briandowns/spinner v1.16.0 h1:DFmp6hEaIx2QXXuqSJmtfSBSAjRmpGiKG6ip2Wm/yOs=
7575
github.com/briandowns/spinner v1.16.0/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ=
7676
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=

internal/cmd/update.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"cdr.dev/coder-cli/pkg/clog"
2323
"golang.org/x/xerrors"
2424

25-
"github.com/blang/semver/v4"
25+
"github.com/Masterminds/semver/v3"
2626
"github.com/manifoldco/promptui"
2727
"github.com/spf13/afero"
2828
"github.com/spf13/cobra"
@@ -116,15 +116,15 @@ func (u *updater) Run(ctx context.Context, force bool, coderURLString string) er
116116
clog.LogInfo(fmt.Sprintf("Coder instance at %q reports version %s", coderURL.String(), desiredVersion.String()))
117117
clog.LogInfo(fmt.Sprintf("Current version of coder-cli is %s", version.Version))
118118

119-
if currentVersion, err := semver.Make(u.versionF()); err == nil {
119+
if currentVersion, err := semver.StrictNewVersion(u.versionF()); err == nil {
120120
if desiredVersion.Compare(currentVersion) == 0 {
121121
clog.LogInfo("Up to date!")
122122
return nil
123123
}
124124
}
125125

126126
if !force {
127-
label := fmt.Sprintf("Update coder-cli to version %s", desiredVersion.FinalizeVersion())
127+
label := fmt.Sprintf("Do you want to download version %s instead", desiredVersion)
128128
if _, err := u.confirmF(label); err != nil {
129129
return clog.Fatal("failed to confirm update", clog.Tipf(`use "--force" to update without confirmation`))
130130
}
@@ -188,7 +188,7 @@ func (u *updater) Run(ctx context.Context, force bool, coderURLString string) er
188188
return clog.Fatal("failed to update coder binary in-place", clog.Causef(err.Error()))
189189
}
190190

191-
clog.LogSuccess("Updated coder CLI to version " + desiredVersion.FinalizeVersion())
191+
clog.LogSuccess("Updated coder CLI to version " + desiredVersion.String())
192192
return nil
193193
}
194194

@@ -206,7 +206,18 @@ func makeDownloadURL(version *semver.Version, ostype, archtype string) string {
206206
default:
207207
ext = "zip"
208208
}
209-
return fmt.Sprintf(template, version, ostype, archetype, ext)
209+
var b bytes.Buffer
210+
fmt.Fprintf(&b, "%d", version.Major())
211+
fmt.Fprint(&b, ".")
212+
fmt.Fprintf(&b, "%d", version.Minor())
213+
fmt.Fprint(&b, ".")
214+
fmt.Fprintf(&b, "%d", version.Patch())
215+
if version.Prerelease() != "" {
216+
fmt.Fprint(&b, "-")
217+
fmt.Fprint(&b, version.Prerelease())
218+
}
219+
220+
return fmt.Sprintf(template, b.String(), ostype, archtype, ext)
210221
}
211222

212223
func extractFromArchive(path string, archive []byte) ([]byte, error) {
@@ -295,22 +306,22 @@ func getCoderConfigURL() (*url.URL, error) {
295306

296307
// XXX: coder.Client requires an API key, but we may not be logged into the coder instance for which we
297308
// want to determine the version. We don't need an API key to sniff the version header.
298-
func getAPIVersionUnauthed(client getter, baseURL url.URL) (semver.Version, error) {
309+
func getAPIVersionUnauthed(client getter, baseURL url.URL) (*semver.Version, error) {
299310
baseURL.Path = path.Join(baseURL.Path, "/api")
300311
resp, err := client.Get(baseURL.String())
301312
if err != nil {
302-
return semver.Version{}, xerrors.Errorf("get %s: %w", baseURL.String(), err)
313+
return nil, xerrors.Errorf("get %s: %w", baseURL.String(), err)
303314
}
304315
defer resp.Body.Close()
305316

306317
versionHdr := resp.Header.Get("coder-version")
307318
if versionHdr == "" {
308-
return semver.Version{}, xerrors.Errorf("URL %s response missing coder-version header", baseURL.String())
319+
return nil, xerrors.Errorf("URL %s response missing coder-version header", baseURL.String())
309320
}
310321

311-
version, err := semver.Parse(versionHdr)
322+
version, err := semver.StrictNewVersion(versionHdr)
312323
if err != nil {
313-
return semver.Version{}, xerrors.Errorf("parsing coder-version header: %w", err)
324+
return nil, xerrors.Errorf("parsing coder-version header: %w", err)
314325
}
315326

316327
return version, nil

internal/cmd/update_test.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ const (
2424
fakeCoderURL = "https://my.cdr.dev"
2525
fakeNewVersion = "1.23.4-rc.5+678-gabcdef-12345678"
2626
fakeOldVersion = "1.22.4-rc.5+678-gabcdef-12345678"
27-
fakeReleaseURLLinux = "https://github.com/cdr/coder-cli/releases/download/v1.23.4/coder-cli-linux-amd64.tar.gz"
28-
fakeReleaseURLWindows = "https://github.com/cdr/coder-cli/releases/download/v1.23.4/coder-cli-windows-amd64.zip"
27+
fakeReleaseURLLinux = "https://github.com/cdr/coder-cli/releases/download/v1.23.4-rc.5/coder-cli-linux-amd64.tar.gz"
28+
fakeReleaseURLWindows = "https://github.com/cdr/coder-cli/releases/download/v1.23.4-rc.5/coder-cli-windows-amd64.zip"
2929
)
3030

3131
func Test_updater_run(t *testing.T) {
@@ -221,7 +221,7 @@ func Test_updater_run(t *testing.T) {
221221
assertFileContent(t, p.Fakefs, fakeExePathLinux, fakeOldVersion)
222222
})
223223

224-
run(t, "update coder - invalid archive", func(t *testing.T, p *params) {
224+
run(t, "update coder - invalid tgz archive", func(t *testing.T, p *params) {
225225
fakeFile(t, p.Fakefs, fakeExePathLinux, 0755, fakeOldVersion)
226226
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil)
227227
p.HttpClient.M[fakeReleaseURLLinux] = newFakeGetterResponse([]byte{}, 200, variadicS(), nil)
@@ -234,6 +234,21 @@ func Test_updater_run(t *testing.T) {
234234
assertFileContent(t, p.Fakefs, fakeExePathLinux, fakeOldVersion)
235235
})
236236

237+
run(t, "update coder - invalid zip archive", func(t *testing.T, p *params) {
238+
p.OsF = func() string { return "windows" }
239+
p.ExecutablePath = fakeExePathWindows
240+
fakeFile(t, p.Fakefs, fakeExePathWindows, 0755, fakeOldVersion)
241+
p.HttpClient.M[fakeCoderURL+"/api"] = newFakeGetterResponse([]byte{}, 401, variadicS("coder-version: "+fakeNewVersion), nil)
242+
p.HttpClient.M[fakeReleaseURLWindows] = newFakeGetterResponse([]byte{}, 200, variadicS(), nil)
243+
p.VersionF = func() string { return fakeOldVersion }
244+
p.ConfirmF = fakeConfirmYes
245+
u := fromParams(p)
246+
assertFileContent(t, p.Fakefs, p.ExecutablePath, fakeOldVersion)
247+
err := u.Run(p.Ctx, false, fakeCoderURL)
248+
assert.ErrorContains(t, "update coder - invalid archive", err, "failed to extract coder binary from archive")
249+
assertFileContent(t, p.Fakefs, p.ExecutablePath, fakeOldVersion)
250+
})
251+
237252
run(t, "update coder - read-only fs", func(t *testing.T, p *params) {
238253
rwfs := p.Fakefs
239254
p.Fakefs = afero.NewReadOnlyFs(rwfs)

0 commit comments

Comments
 (0)