Skip to content

Commit 4211b93

Browse files
authored
feat: support to setup the provider (#336)
Co-authored-by: rick <[email protected]>
1 parent 48dbddc commit 4211b93

File tree

5 files changed

+203
-23
lines changed

5 files changed

+203
-23
lines changed

cmd/root.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
"runtime"
88

9+
"github.com/AlecAivazis/survey/v2/terminal"
910
extpkg "github.com/linuxsuren/cobra-extension/pkg"
1011
extver "github.com/linuxsuren/cobra-extension/version"
1112
"github.com/spf13/cobra"
@@ -23,8 +24,15 @@ func NewRoot(cxt context.Context) (cmd *cobra.Command) {
2324
panic(err)
2425
}
2526

27+
v := viper.GetViper()
28+
stdio := terminal.Stdio{
29+
Out: os.Stdout,
30+
In: os.Stdin,
31+
Err: os.Stderr,
32+
}
33+
2634
cmd.AddCommand(
27-
newGetCmd(cxt), newInstallCmd(cxt), newFetchCmd(cxt), newSearchCmd(cxt), newSetupCommand(),
35+
newGetCmd(cxt), newInstallCmd(cxt), newFetchCmd(cxt), newSearchCmd(cxt), newSetupCommand(v, stdio),
2836
extver.NewVersionCmd("linuxsuren", "http-downloader", "hd", nil),
2937
extpkg.NewCompletionCmd(cmd))
3038
return

cmd/setup.go

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@ import (
66
"path"
77

88
"github.com/AlecAivazis/survey/v2"
9+
"github.com/AlecAivazis/survey/v2/terminal"
910
"github.com/spf13/cobra"
1011
"github.com/spf13/viper"
1112
)
1213

13-
func newSetupCommand() (cmd *cobra.Command) {
14-
opt := &setupOption{}
14+
func newSetupCommand(v *viper.Viper, stdio terminal.Stdio) (cmd *cobra.Command) {
15+
opt := &setupOption{
16+
stdio: stdio,
17+
v: v,
18+
}
1519
cmd = &cobra.Command{
1620
Use: "setup",
1721
Short: "Init the configuration of hd",
@@ -21,18 +25,27 @@ func newSetupCommand() (cmd *cobra.Command) {
2125
}
2226

2327
type setupOption struct {
28+
stdio terminal.Stdio
29+
v *viper.Viper
2430
}
2531

2632
func (o *setupOption) runE(cmd *cobra.Command, args []string) (err error) {
27-
selector := &survey.Select{
28-
Message: "Select proxy-github",
29-
Options: []string{"gh.api.99988866.xyz", "ghproxy.com", "mirror.ghproxy.com", ""},
30-
Default: viper.Get("proxy-github"),
33+
var (
34+
proxyGitHub string
35+
provider string
36+
)
37+
38+
if proxyGitHub, err = selectFromList([]string{"ghproxy.com", "gh.api.99988866.xyz", "mirror.ghproxy.com", ""},
39+
o.v.GetString("proxy-github"),
40+
"Select proxy-github", o.stdio); err == nil {
41+
o.v.Set("proxy-github", proxyGitHub)
42+
} else {
43+
return
3144
}
3245

33-
var choose string
34-
if err = survey.AskOne(selector, &choose); err == nil {
35-
viper.Set("proxy-github", choose)
46+
if provider, err = selectFromList([]string{"github", "gitee"}, o.v.GetString("provider"),
47+
"Select provider", o.stdio); err == nil {
48+
o.v.Set("provider", provider)
3649
} else {
3750
return
3851
}
@@ -43,6 +56,16 @@ func (o *setupOption) runE(cmd *cobra.Command, args []string) (err error) {
4356
return
4457
}
4558

46-
err = viper.WriteConfigAs(path.Join(configDir, "hd.yaml"))
59+
err = o.v.WriteConfigAs(path.Join(configDir, "hd.yaml"))
60+
return
61+
}
62+
63+
func selectFromList(items []string, defaultItem, title string, stdio terminal.Stdio) (val string, err error) {
64+
selector := &survey.Select{
65+
Message: title,
66+
Options: items,
67+
Default: defaultItem,
68+
}
69+
err = survey.AskOne(selector, &val, survey.WithStdio(stdio.In, stdio.Out, stdio.Err))
4770
return
4871
}

cmd/setup_test.go

Lines changed: 146 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,154 @@
11
package cmd
22

33
import (
4-
"github.com/stretchr/testify/assert"
54
"testing"
5+
6+
"github.com/AlecAivazis/survey/v2/terminal"
7+
expect "github.com/Netflix/go-expect"
8+
pseudotty "github.com/creack/pty"
9+
"github.com/hinshun/vt10x"
10+
"github.com/spf13/afero"
11+
"github.com/spf13/viper"
12+
"github.com/stretchr/testify/assert"
613
)
714

815
func Test_newSetupCommand(t *testing.T) {
9-
cmd := newSetupCommand()
10-
assert.Equal(t, "setup", cmd.Name())
16+
t.Run("normal", func(t *testing.T) {
17+
RunTest(t, func(c expectConsole) {
18+
c.ExpectString("Select proxy-github")
19+
c.Send("99988866")
20+
c.SendLine("")
21+
22+
c.ExpectString("Select provider")
23+
c.Send("gitee")
24+
c.SendLine("")
25+
c.ExpectEOF()
26+
}, func(tr terminal.Stdio) error {
27+
fs := afero.NewMemMapFs()
28+
v := viper.New()
29+
v.SetFs(fs)
30+
v.Set("provider", "github")
31+
32+
cmd := newSetupCommand(v, tr)
33+
assert.Equal(t, "setup", cmd.Name())
34+
35+
err := cmd.Execute()
36+
assert.Nil(t, err)
37+
assert.Equal(t, "gh.api.99988866.xyz", v.GetString("proxy-github"))
38+
assert.Equal(t, "gitee", v.GetString("provider"))
39+
return err
40+
})
41+
})
42+
43+
t.Run("test the default value", func(t *testing.T) {
44+
RunTest(t, func(c expectConsole) {
45+
c.ExpectString("Select proxy-github")
46+
c.SendLine("")
47+
48+
c.ExpectString("Select provider")
49+
c.SendLine("")
50+
c.ExpectEOF()
51+
}, func(tr terminal.Stdio) error {
52+
fs := afero.NewMemMapFs()
53+
v := viper.New()
54+
v.SetFs(fs)
55+
v.Set("provider", "gitee")
56+
v.Set("proxy-github", "gh.api.99988866.xyz")
57+
58+
cmd := newSetupCommand(v, tr)
59+
assert.Equal(t, "setup", cmd.Name())
60+
61+
err := cmd.Execute()
62+
assert.Nil(t, err)
63+
assert.Equal(t, "gh.api.99988866.xyz", v.GetString("proxy-github"))
64+
assert.Equal(t, "gitee", v.GetString("provider"))
65+
return err
66+
})
67+
})
68+
}
69+
70+
func TestSelectFromList(t *testing.T) {
71+
RunTest(t, func(c expectConsole) {
72+
c.ExpectString("title")
73+
c.SendLine(string(terminal.KeyArrowDown))
74+
c.SendLine("")
75+
c.ExpectEOF()
76+
}, func(tr terminal.Stdio) error {
77+
val, err := selectFromList([]string{"one", "two", "three"}, "", "title", tr)
78+
assert.Equal(t, "two", val)
79+
return err
80+
})
81+
}
82+
83+
type expectConsole interface {
84+
ExpectString(string)
85+
ExpectEOF()
86+
SendLine(string)
87+
Send(string)
88+
}
89+
90+
func RunTest(t *testing.T, procedure func(expectConsole), test func(terminal.Stdio) error) {
91+
t.Helper()
92+
t.Parallel()
93+
94+
pty, tty, err := pseudotty.Open()
95+
if err != nil {
96+
t.Fatalf("failed to open pseudotty: %v", err)
97+
}
98+
99+
term := vt10x.New(vt10x.WithWriter(tty))
100+
c, err := expect.NewConsole(expect.WithStdin(pty), expect.WithStdout(term), expect.WithCloser(pty, tty))
101+
if err != nil {
102+
t.Fatalf("failed to create console: %v", err)
103+
}
104+
defer c.Close()
105+
106+
donec := make(chan struct{})
107+
go func() {
108+
defer close(donec)
109+
procedure(&consoleWithErrorHandling{console: c, t: t})
110+
}()
111+
112+
stdio := terminal.Stdio{In: c.Tty(), Out: c.Tty(), Err: c.Tty()}
113+
if err := test(stdio); err != nil {
114+
t.Error(err)
115+
}
116+
117+
if err := c.Tty().Close(); err != nil {
118+
t.Errorf("error closing Tty: %v", err)
119+
}
120+
<-donec
121+
}
122+
123+
type consoleWithErrorHandling struct {
124+
console *expect.Console
125+
t *testing.T
126+
}
127+
128+
func (c *consoleWithErrorHandling) ExpectString(s string) {
129+
if _, err := c.console.ExpectString(s); err != nil {
130+
c.t.Helper()
131+
c.t.Fatalf("ExpectString(%q) = %v", s, err)
132+
}
133+
}
134+
135+
func (c *consoleWithErrorHandling) SendLine(s string) {
136+
if _, err := c.console.SendLine(s); err != nil {
137+
c.t.Helper()
138+
c.t.Fatalf("SendLine(%q) = %v", s, err)
139+
}
140+
}
141+
142+
func (c *consoleWithErrorHandling) Send(s string) {
143+
if _, err := c.console.Send(s); err != nil {
144+
c.t.Helper()
145+
c.t.Fatalf("Send(%q) = %v", s, err)
146+
}
147+
}
148+
149+
func (c *consoleWithErrorHandling) ExpectEOF() {
150+
if _, err := c.console.ExpectEOF(); err != nil {
151+
c.t.Helper()
152+
c.t.Fatalf("ExpectEOF() = %v", err)
153+
}
11154
}

go.mod

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
github.com/google/go-github/v29 v29.0.3
1010
github.com/gosuri/uiprogress v0.0.1
1111
github.com/h2non/gock v1.0.9
12+
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec
1213
github.com/linuxsuren/cobra-extension v0.0.16
1314
github.com/mitchellh/go-homedir v1.1.0
1415
github.com/onsi/ginkgo v1.16.5
@@ -21,11 +22,16 @@ require (
2122
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
2223
)
2324

25+
require github.com/creack/pty v1.1.17
26+
27+
require github.com/prometheus/client_golang v1.11.1 // indirect
28+
2429
require (
2530
github.com/Microsoft/go-winio v0.4.16 // indirect
31+
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2
2632
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
2733
github.com/acomagu/bufpipe v1.0.3 // indirect
28-
github.com/blang/semver/v4 v4.0.0 // indirect
34+
github.com/blang/semver/v4 v4.0.0
2935
github.com/davecgh/go-spew v1.1.1 // indirect
3036
github.com/emirpasic/gods v1.12.0 // indirect
3137
github.com/fsnotify/fsnotify v1.5.1 // indirect
@@ -49,15 +55,14 @@ require (
4955
github.com/nxadm/tail v1.4.8 // indirect
5056
github.com/pelletier/go-toml v1.9.4 // indirect
5157
github.com/pmezard/go-difflib v1.0.0 // indirect
52-
github.com/prometheus/client_golang v1.11.1 // indirect
5358
github.com/sergi/go-diff v1.1.0 // indirect
54-
github.com/spf13/afero v1.6.0 // indirect
59+
github.com/spf13/afero v1.6.0
5560
github.com/spf13/cast v1.4.1 // indirect
5661
github.com/spf13/jwalterweatherman v1.1.0 // indirect
5762
github.com/subosito/gotenv v1.2.0 // indirect
5863
github.com/xanzy/ssh-agent v0.3.0 // indirect
5964
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
60-
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
65+
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
6166
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
6267
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
6368
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect

go.sum

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
5151
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
5252
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
5353
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
54-
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
5554
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
55+
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
56+
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
5657
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
5758
github.com/Pallinder/go-randomdata v1.2.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y=
5859
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
@@ -106,8 +107,9 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
106107
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
107108
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
108109
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
109-
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
110110
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
111+
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
112+
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
111113
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
112114
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
113115
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -280,8 +282,9 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
280282
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
281283
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
282284
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
283-
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
284285
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
286+
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
287+
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
285288
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
286289
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
287290
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -737,7 +740,6 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
737740
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
738741
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
739742
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
740-
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
741743
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
742744
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
743745
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -753,7 +755,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
753755
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
754756
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
755757
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
756-
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
757758
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
758759
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
759760
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=

0 commit comments

Comments
 (0)