Skip to content

Commit c9ab375

Browse files
authored
feat: check the version before install (#322)
* feat: check the version before install * add unit tests * support to fetch repo as background task
1 parent 9dec242 commit c9ab375

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1356
-423
lines changed

.github/workflows/pull-request.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ jobs:
3434
run: |
3535
sudo ./release/http-downloader_linux_amd64_v1/hd install jenkins-zh/jenkins-cli/jcli
3636
jcli version
37-
38-
sudo ./release/http-downloader_linux_amd64_v1/hd install ks
39-
ks version
4037
- name: Run Trivy vulnerability scanner
4138
uses: aquasecurity/[email protected]
4239
if: github.event_name == 'pull_request'

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ bin/
44
*/**/*.xml
55
coverage.out
66
node_modules
7+
release/

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ gen-mock:
3232

3333
update:
3434
git fetch
35-
git reset --hard origin/$(shell git branch --show-current)
35+
git reset --hard origin/$(shell git branch --show-current)
36+
goreleaser:
37+
goreleaser build --snapshot --rm-dist

cmd/fetch.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ package cmd
33
import (
44
"context"
55
"fmt"
6+
"github.com/linuxsuren/http-downloader/pkg"
7+
"os"
8+
69
"github.com/linuxsuren/http-downloader/pkg/installer"
710
"github.com/spf13/cobra"
8-
"os"
911
)
1012

1113
func newFetchCmd(context.Context) (cmd *cobra.Command) {
12-
opt := &fetchOption{}
14+
opt := &fetchOption{
15+
fetcher: &installer.DefaultFetcher{},
16+
}
1317
cmd = &cobra.Command{
1418
Use: "fetch",
1519
Short: "Fetch the latest hd config",
@@ -28,31 +32,30 @@ func newFetchCmd(context.Context) (cmd *cobra.Command) {
2832
return
2933
}
3034

31-
func (o *fetchOption) preRunE(_ *cobra.Command, _ []string) (err error) {
32-
fetcher := &installer.DefaultFetcher{}
35+
func (o *fetchOption) preRunE(c *cobra.Command, _ []string) (err error) {
36+
if c.Context() != nil {
37+
o.fetcher.SetContext(c.Context())
38+
}
3339
if o.reset {
3440
var configDir string
35-
if configDir, err = fetcher.GetConfigDir(); err == nil {
36-
if err = os.RemoveAll(configDir); err != nil {
37-
err = fmt.Errorf("failed to remove directory: %s, error %v", configDir, err)
38-
return
39-
}
41+
if configDir, err = o.fetcher.GetConfigDir(); err == nil {
42+
err = os.RemoveAll(configDir)
43+
err = pkg.ErrorWrap(err, "failed to remove directory: %s, error %v", configDir, err)
4044
} else {
4145
err = fmt.Errorf("failed to get config directory, error %v", err)
42-
return
4346
}
4447
}
4548
return
4649
}
4750

4851
func (o *fetchOption) runE(cmd *cobra.Command, _ []string) (err error) {
49-
fetcher := &installer.DefaultFetcher{}
50-
return fetcher.FetchLatestRepo(o.Provider, o.branch, cmd.OutOrStdout())
52+
return o.fetcher.FetchLatestRepo(o.Provider, o.branch, cmd.OutOrStdout())
5153
}
5254

5355
type fetchOption struct {
5456
searchOption
5557

56-
branch string
57-
reset bool
58+
branch string
59+
reset bool
60+
fetcher installer.Fetcher
5861
}

cmd/fetch_test.go

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@ package cmd
22

33
import (
44
"context"
5-
"github.com/stretchr/testify/assert"
5+
"errors"
6+
"os"
7+
"path"
68
"testing"
9+
10+
"github.com/linuxsuren/http-downloader/pkg/installer"
11+
"github.com/spf13/cobra"
12+
"github.com/stretchr/testify/assert"
713
)
814

915
func Test_newFetchCmd(t *testing.T) {
@@ -29,3 +35,69 @@ func Test_newFetchCmd(t *testing.T) {
2935
})
3036
}
3137
}
38+
39+
func TestFetchPreRunE(t *testing.T) {
40+
tests := []struct {
41+
name string
42+
opt *fetchOption
43+
hasErr bool
44+
}{{
45+
name: "not reset",
46+
opt: &fetchOption{},
47+
hasErr: false,
48+
}, {
49+
name: "reset, cannot get config dir",
50+
opt: &fetchOption{
51+
reset: true,
52+
fetcher: &installer.FakeFetcher{
53+
GetConfigDirErr: errors.New("no config dir"),
54+
},
55+
},
56+
hasErr: true,
57+
}, {
58+
name: "reset, remove dir",
59+
opt: &fetchOption{
60+
reset: true,
61+
fetcher: &installer.FakeFetcher{
62+
ConfigDir: path.Join(os.TempDir(), "hd-config"),
63+
},
64+
},
65+
hasErr: false,
66+
}}
67+
for _, tt := range tests {
68+
t.Run(tt.name, func(t *testing.T) {
69+
c := &cobra.Command{}
70+
err := tt.opt.preRunE(c, nil)
71+
if tt.hasErr {
72+
assert.NotNil(t, err)
73+
} else {
74+
assert.Nil(t, err)
75+
}
76+
})
77+
}
78+
}
79+
80+
func TestFetchRunE(t *testing.T) {
81+
tests := []struct {
82+
name string
83+
opt *fetchOption
84+
hasErr bool
85+
}{{
86+
name: "normal",
87+
opt: &fetchOption{
88+
fetcher: &installer.FakeFetcher{},
89+
},
90+
hasErr: false,
91+
}}
92+
for _, tt := range tests {
93+
t.Run(tt.name, func(t *testing.T) {
94+
c := &cobra.Command{}
95+
err := tt.opt.runE(c, nil)
96+
if tt.hasErr {
97+
assert.NotNil(t, err)
98+
} else {
99+
assert.Nil(t, err)
100+
}
101+
})
102+
}
103+
}

cmd/get.go

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"bytes"
45
"context"
56
"fmt"
67
"net/http"
@@ -9,6 +10,7 @@ import (
910
"path"
1011
"runtime"
1112
"strings"
13+
"sync"
1214

1315
"github.com/linuxsuren/http-downloader/pkg"
1416
"github.com/linuxsuren/http-downloader/pkg/installer"
@@ -20,9 +22,7 @@ import (
2022

2123
// newGetCmd return the get command
2224
func newGetCmd(ctx context.Context) (cmd *cobra.Command) {
23-
opt := &downloadOption{
24-
RoundTripper: getRoundTripper(ctx),
25-
}
25+
opt := newDownloadOption(ctx)
2626
cmd = &cobra.Command{
2727
Use: "get",
2828
Short: "download the file",
@@ -68,8 +68,18 @@ func newGetCmd(ctx context.Context) (cmd *cobra.Command) {
6868
return
6969
}
7070

71+
func newDownloadOption(ctx context.Context) *downloadOption {
72+
return &downloadOption{
73+
RoundTripper: getRoundTripper(ctx),
74+
fetcher: &installer.DefaultFetcher{},
75+
wait: &sync.WaitGroup{},
76+
}
77+
}
78+
7179
type downloadOption struct {
7280
searchOption
81+
cancel context.CancelFunc
82+
wait *sync.WaitGroup
7383

7484
URL string
7585
Category string
@@ -94,12 +104,13 @@ type downloadOption struct {
94104
PrintCategories bool
95105

96106
// inner fields
97-
name string
98-
Tar bool
99-
Package *installer.HDConfig
100-
org string
101-
repo string
102-
fetcher installer.Fetcher
107+
name string
108+
Tar bool
109+
Package *installer.HDConfig
110+
org string
111+
repo string
112+
fetcher installer.Fetcher
113+
ExpectVersion string // should be like >v1.1.0
103114
}
104115

105116
const (
@@ -111,14 +122,19 @@ const (
111122

112123
func (o *downloadOption) fetch() (err error) {
113124
if !o.Fetch {
125+
o.wait.Add(1)
126+
go func() {
127+
// no need to handle the error due to this is a background task
128+
if o.fetcher != nil {
129+
err = o.fetcher.FetchLatestRepo(o.Provider, installer.ConfigBranch, bytes.NewBuffer(nil))
130+
}
131+
o.wait.Done()
132+
}()
114133
return
115134
}
116135

117136
// fetch the latest config
118137
fmt.Println("start to fetch the config")
119-
if o.fetcher == nil {
120-
o.fetcher = &installer.DefaultFetcher{}
121-
}
122138
if err = o.fetcher.FetchLatestRepo(o.Provider, installer.ConfigBranch, sysos.Stdout); err != nil {
123139
err = fmt.Errorf("unable to fetch the latest config, error: %v", err)
124140
return
@@ -133,6 +149,11 @@ func (o *downloadOption) preRunE(cmd *cobra.Command, args []string) (err error)
133149
return
134150
}
135151

152+
if cmd.Context() != nil {
153+
ctx, cancel := context.WithCancel(cmd.Context())
154+
o.cancel = cancel
155+
o.fetcher.SetContext(ctx)
156+
}
136157
if err = o.fetch(); err != nil {
137158
return
138159
}
@@ -147,6 +168,7 @@ func (o *downloadOption) preRunE(cmd *cobra.Command, args []string) (err error)
147168
}
148169

149170
targetURL := args[0]
171+
o.Package = &installer.HDConfig{}
150172
if !strings.HasPrefix(targetURL, "http://") && !strings.HasPrefix(targetURL, "https://") {
151173
ins := &installer.Installer{
152174
Provider: o.Provider,
@@ -186,6 +208,13 @@ func (o *downloadOption) preRunE(cmd *cobra.Command, args []string) (err error)
186208
}
187209

188210
func (o *downloadOption) runE(cmd *cobra.Command, args []string) (err error) {
211+
defer func() {
212+
if o.cancel != nil {
213+
o.cancel()
214+
o.wait.Wait()
215+
}
216+
}()
217+
189218
// only print the schema for documentation
190219
if o.PrintSchema {
191220
var data []byte

cmd/get_test.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"net/http"
1010
"os"
1111
"path"
12+
"sync"
1213
"testing"
1314
"time"
1415

@@ -68,7 +69,9 @@ func Test_newGetCmd(t *testing.T) {
6869
}
6970

7071
func TestFetch(t *testing.T) {
71-
opt := &downloadOption{}
72+
opt := &downloadOption{
73+
wait: &sync.WaitGroup{},
74+
}
7275
opt.Fetch = false
7376
opt.fetcher = &installer.FakeFetcher{FetchLatestRepoErr: errors.New("fake")}
7477

@@ -85,7 +88,9 @@ func TestFetch(t *testing.T) {
8588
}
8689

8790
func TestPreRunE(t *testing.T) {
88-
opt := &downloadOption{}
91+
opt := &downloadOption{
92+
wait: &sync.WaitGroup{},
93+
}
8994
opt.Fetch = true
9095
opt.fetcher = &installer.FakeFetcher{FetchLatestRepoErr: errors.New("fake")}
9196
opt.PrintSchema = true
@@ -94,17 +99,18 @@ func TestPreRunE(t *testing.T) {
9499
assert.Nil(t, opt.preRunE(nil, nil))
95100

96101
// failed to fetch
102+
fakeC := &cobra.Command{}
97103
opt.PrintSchema = false
98-
assert.NotNil(t, opt.preRunE(nil, nil))
104+
assert.NotNil(t, opt.preRunE(fakeC, nil))
99105

100106
// pripnt categories
101107
opt.fetcher = &installer.FakeFetcher{}
102108
opt.PrintCategories = true
103-
assert.Nil(t, opt.preRunE(nil, nil))
109+
assert.Nil(t, opt.preRunE(fakeC, nil))
104110

105111
// not args provided
106112
opt.PrintCategories = false
107-
assert.NotNil(t, opt.preRunE(nil, nil))
113+
assert.NotNil(t, opt.preRunE(fakeC, nil))
108114
}
109115

110116
func TestRunE(t *testing.T) {

0 commit comments

Comments
 (0)