Skip to content

Commit e5b6fc6

Browse files
authored
fix name and version split error when installing the app (#135)
* fix name and version split error when installing the app
1 parent 2a0d4b1 commit e5b6fc6

File tree

3 files changed

+229
-36
lines changed

3 files changed

+229
-36
lines changed

pkg/common/util.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io/ioutil"
66
"os"
77
"path/filepath"
8+
"regexp"
89
)
910

1011
// GetOrDefault returns the value or a default value from a map
@@ -74,3 +75,8 @@ func Exist(name string) bool {
7475
_, err := os.Stat(name)
7576
return err == nil
7677
}
78+
79+
// ParseVersionNum split version from release or tag
80+
func ParseVersionNum(release string) string {
81+
return regexp.MustCompile(`^.*v`).ReplaceAllString(release, "")
82+
}

pkg/installer/check.go

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
sysos "os"
1717
"path"
1818
"path/filepath"
19-
"regexp"
2019
"runtime"
2120
"strings"
2221
"text/template"
@@ -73,26 +72,32 @@ func (o *Installer) CheckDepAndInstall(tools map[string]string) (err error) {
7372
return
7473
}
7574

76-
// ProviderURLParse parse the URL
77-
func (o *Installer) ProviderURLParse(path string, acceptPreRelease bool) (packageURL string, err error) {
78-
packageURL = path
79-
if o.Fetch {
80-
// fetch the latest config
81-
fmt.Println("start to fetch the config")
82-
if err = FetchLatestRepo(o.Provider, ConfigBranch, sysos.Stdout); err != nil {
83-
err = fmt.Errorf("unable to fetch the latest config, error: %v", err)
84-
return
85-
}
86-
}
75+
// GetVersion parse install app info
76+
func (o *Installer) GetVersion(path string) (version string, err error) {
8777

8878
var (
89-
org string
90-
repo string
91-
name string
92-
version string
79+
org string
80+
repo string
81+
name string
9382
)
9483

95-
addr := strings.Split(packageURL, "/")
84+
// 1. split app info and app version
85+
var appName string
86+
appInfo := strings.Split(path, "@")
87+
switch len(appInfo) {
88+
case 1:
89+
appName = appInfo[0]
90+
version = "latest"
91+
case 2:
92+
appName = appInfo[0]
93+
version = appInfo[1]
94+
default:
95+
err = fmt.Errorf("only support format xxx or xxx@version")
96+
return
97+
}
98+
99+
// 2. split app info
100+
addr := strings.Split(appName, "/")
96101
if len(addr) >= 2 {
97102
org = addr[0]
98103
repo = addr[1]
@@ -113,7 +118,7 @@ func (o *Installer) ProviderURLParse(path string, acceptPreRelease bool) (packag
113118

114119
fmt.Printf("target package is %s/%s\n", org, repo)
115120
} else {
116-
err = fmt.Errorf("only support format xx, xx/xx or xx/xx/xx")
121+
err = fmt.Errorf("name only support format xx, xx/xx or xx/xx/xx")
117122
return
118123
}
119124

@@ -125,26 +130,40 @@ func (o *Installer) ProviderURLParse(path string, acceptPreRelease bool) (packag
125130

126131
o.Org = org
127132
o.Repo = repo
133+
o.Name = name
128134

129-
// extract version from name
130-
if strings.Contains(name, "@") {
131-
nameWithVer := strings.Split(name, "@")
132-
name = nameWithVer[0]
133-
version = nameWithVer[1]
135+
return
136+
}
134137

135-
packageURL = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/%s-%s-%s.tar.gz",
136-
org, repo, version, name, o.OS, o.Arch)
137-
} else if name != "" {
138-
version = "latest"
138+
// ProviderURLParse parse the URL
139+
func (o *Installer) ProviderURLParse(path string, acceptPreRelease bool) (packageURL string, err error) {
140+
packageURL = path
141+
if o.Fetch {
142+
// fetch the latest config
143+
fmt.Println("start to fetch the config")
144+
if err = FetchLatestRepo(o.Provider, ConfigBranch, sysos.Stdout); err != nil {
145+
err = fmt.Errorf("unable to fetch the latest config, error: %v", err)
146+
return
147+
}
148+
}
149+
150+
version, err := o.GetVersion(packageURL)
151+
if err != nil {
152+
return
153+
}
154+
155+
if version == "latest" {
139156
packageURL = fmt.Sprintf("https://github.com/%s/%s/releases/%s/download/%s-%s-%s.tar.gz",
140-
org, repo, version, name, o.OS, o.Arch)
157+
o.Org, o.Repo, version, o.Name, o.OS, o.Arch)
158+
} else {
159+
packageURL = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/%s-%s-%s.tar.gz",
160+
o.Org, o.Repo, version, o.Name, o.OS, o.Arch)
141161
}
142-
o.Name = name
143162

144163
// try to parse from config
145164
userHome, _ := homedir.Dir()
146165
configDir := userHome + "/.config/hd-home"
147-
matchedFile := configDir + "/config/" + org + "/" + repo + ".yml"
166+
matchedFile := configDir + "/config/" + o.Org + "/" + o.Repo + ".yml"
148167
if ok, _ := common.PathExists(matchedFile); ok {
149168
var data []byte
150169
if data, err = ioutil.ReadFile(matchedFile); err == nil {
@@ -168,13 +187,13 @@ func (o *Installer) ProviderURLParse(path string, acceptPreRelease bool) (packag
168187

169188
if version == "latest" || version == "" {
170189
ghClient := pkg.ReleaseClient{
171-
Org: org,
172-
Repo: repo,
190+
Org: o.Org,
191+
Repo: o.Repo,
173192
}
174193
ghClient.Init()
175194
if asset, err := ghClient.GetLatestAsset(acceptPreRelease); err == nil {
176195
hdPkg.Version = url.QueryEscape(asset.TagName) // the version name might have some special string
177-
hdPkg.VersionNum = regexp.MustCompile(`^.*v`).ReplaceAllString(asset.TagName, "")
196+
hdPkg.VersionNum = common.ParseVersionNum(asset.TagName)
178197

179198
version = hdPkg.Version
180199
} else {
@@ -183,12 +202,13 @@ func (o *Installer) ProviderURLParse(path string, acceptPreRelease bool) (packag
183202

184203
if packageURL == "" {
185204
packageURL = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/%s-%s-%s.tar.gz",
186-
org, repo, version, o.Name, o.OS, o.Arch)
205+
o.Org, o.Repo, version, o.Name, o.OS, o.Arch)
187206
}
188207
} else {
208+
hdPkg.VersionNum = common.ParseVersionNum(version)
189209
if packageURL == "" {
190210
packageURL = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/%s-%s-%s.tar.gz",
191-
org, repo, version, name, o.OS, o.Arch)
211+
o.Org, o.Repo, version, o.Name, o.OS, o.Arch)
192212
}
193213
}
194214

@@ -208,7 +228,7 @@ func (o *Installer) ProviderURLParse(path string, acceptPreRelease bool) (packag
208228
var buf bytes.Buffer
209229
if err = tmp.Execute(&buf, hdPkg); err == nil {
210230
packageURL = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/%s",
211-
org, repo, version, buf.String())
231+
o.Org, o.Repo, version, buf.String())
212232

213233
o.Output = buf.String()
214234
} else {

pkg/installer/check_test.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package installer
2+
3+
import (
4+
"fmt"
5+
"github.com/stretchr/testify/assert"
6+
"runtime"
7+
"testing"
8+
)
9+
10+
func TestGetVersion(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
appInfo string
14+
verify func(o *Installer, version string, t *testing.T)
15+
wantErr bool
16+
}{
17+
{
18+
name: "empty version, repo as default name",
19+
appInfo: "kubernetes-sigs/kustomize",
20+
verify: func(o *Installer, version string, t *testing.T) {
21+
assert.Equal(t, version, "latest")
22+
assert.Equal(t, o.Org, "kubernetes-sigs")
23+
assert.Equal(t, o.Repo, "kustomize")
24+
assert.Equal(t, o.Name, "kustomize")
25+
},
26+
wantErr: false,
27+
},
28+
{
29+
name: "empty version, specific app name",
30+
appInfo: "kubernetes-sigs/kustomize/kustomize",
31+
verify: func(o *Installer, version string, t *testing.T) {
32+
assert.Equal(t, version, "latest")
33+
assert.Equal(t, o.Org, "kubernetes-sigs")
34+
assert.Equal(t, o.Repo, "kustomize")
35+
assert.Equal(t, o.Name, "kustomize")
36+
},
37+
wantErr: false,
38+
},
39+
{
40+
name: "semver version, specific app name",
41+
appInfo: "kubernetes-sigs/kustomize/[email protected]",
42+
verify: func(o *Installer, version string, t *testing.T) {
43+
assert.Equal(t, version, "v1.0")
44+
assert.Equal(t, o.Org, "kubernetes-sigs")
45+
assert.Equal(t, o.Repo, "kustomize")
46+
assert.Equal(t, o.Name, "kustomize")
47+
},
48+
wantErr: false,
49+
},
50+
{
51+
name: "specific version with a slash, specific app name",
52+
appInfo: "kubernetes-sigs/kustomize/kustomize@kustomize/v1.0",
53+
verify: func(o *Installer, version string, t *testing.T) {
54+
assert.Equal(t, version, "kustomize/v1.0")
55+
assert.Equal(t, o.Org, "kubernetes-sigs")
56+
assert.Equal(t, o.Repo, "kustomize")
57+
assert.Equal(t, o.Name, "kustomize")
58+
},
59+
wantErr: false,
60+
},
61+
{
62+
name: "specific version with a underlined, specific app name",
63+
appInfo: "kubernetes-sigs/kustomize/kustomize@kustomize_v1.0",
64+
verify: func(o *Installer, version string, t *testing.T) {
65+
assert.Equal(t, version, "kustomize_v1.0")
66+
assert.Equal(t, o.Org, "kubernetes-sigs")
67+
assert.Equal(t, o.Repo, "kustomize")
68+
assert.Equal(t, o.Name, "kustomize")
69+
},
70+
wantErr: false,
71+
},
72+
}
73+
74+
for _, tt := range tests {
75+
t.Run(tt.name, func(t *testing.T) {
76+
is := &Installer{}
77+
version, err := is.GetVersion(tt.appInfo)
78+
if (err != nil) != tt.wantErr {
79+
t.Errorf("GetVersion error = %v, wantErr %v", err, tt.wantErr)
80+
}
81+
if tt.verify != nil {
82+
tt.verify(is, version, t)
83+
}
84+
})
85+
}
86+
}
87+
88+
func TestProviderURLParseNoConfig(t *testing.T) {
89+
tests := []struct {
90+
name string
91+
packageURL string
92+
verify func(o *Installer, packageURL string, t *testing.T)
93+
wantErr bool
94+
}{
95+
{
96+
name: "empty version, repo as default name",
97+
packageURL: "orgtest/repotest",
98+
verify: func(o *Installer, packageURL string, t *testing.T) {
99+
expectURL := fmt.Sprintf(
100+
"https://github.com/orgtest/repotest/releases/latest/download/repotest-%s-%s.tar.gz",
101+
o.OS, o.Arch)
102+
assert.Equal(t, packageURL, expectURL)
103+
},
104+
wantErr: false,
105+
},
106+
{
107+
name: "empty version, specific app name",
108+
packageURL: "orgtest/repotest/hello",
109+
verify: func(o *Installer, packageURL string, t *testing.T) {
110+
expectURL := fmt.Sprintf(
111+
"https://github.com/orgtest/repotest/releases/latest/download/hello-%s-%s.tar.gz",
112+
o.OS, o.Arch)
113+
assert.Equal(t, packageURL, expectURL)
114+
},
115+
wantErr: false,
116+
},
117+
{
118+
name: "semver version, specific app name",
119+
packageURL: "orgtest/repotest/[email protected]",
120+
verify: func(o *Installer, packageURL string, t *testing.T) {
121+
expectURL := fmt.Sprintf(
122+
"https://github.com/orgtest/repotest/releases/download/v1.0/hello-%s-%s.tar.gz",
123+
o.OS, o.Arch)
124+
assert.Equal(t, packageURL, expectURL)
125+
},
126+
wantErr: false,
127+
},
128+
{
129+
name: "specific version with a slash, specific app name",
130+
packageURL: "orgtest/repotest/hello@hello/v1.0",
131+
verify: func(o *Installer, packageURL string, t *testing.T) {
132+
expectURL := fmt.Sprintf(
133+
"https://github.com/orgtest/repotest/releases/download/hello/v1.0/hello-%s-%s.tar.gz",
134+
o.OS, o.Arch)
135+
assert.Equal(t, packageURL, expectURL)
136+
},
137+
wantErr: false,
138+
},
139+
{
140+
name: "specific version with a underlined, specific app name",
141+
packageURL: "orgtest/repotest/hello@hello_v1.0",
142+
verify: func(o *Installer, packageURL string, t *testing.T) {
143+
expectURL := fmt.Sprintf(
144+
"https://github.com/orgtest/repotest/releases/download/hello_v1.0/hello-%s-%s.tar.gz",
145+
o.OS, o.Arch)
146+
assert.Equal(t, packageURL, expectURL)
147+
},
148+
wantErr: false,
149+
},
150+
}
151+
152+
for _, tt := range tests {
153+
t.Run(tt.name, func(t *testing.T) {
154+
is := &Installer{
155+
OS: runtime.GOOS,
156+
Arch: runtime.GOARCH,
157+
}
158+
packageURL, err := is.ProviderURLParse(tt.packageURL, false)
159+
if (err != nil) != tt.wantErr {
160+
t.Errorf("ProviderURLParse error = %v, wantErr %v", err, tt.wantErr)
161+
}
162+
if tt.verify != nil {
163+
tt.verify(is, packageURL, t)
164+
}
165+
})
166+
}
167+
}

0 commit comments

Comments
 (0)