Skip to content

Commit 8fc2c77

Browse files
authored
Support to install tools by category (#189)
1 parent 183fe72 commit 8fc2c77

File tree

6 files changed

+100
-9
lines changed

6 files changed

+100
-9
lines changed

cmd/get.go

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ type downloadOption struct {
6666
searchOption
6767

6868
URL string
69+
Category string
6970
Output string
7071
ShowProgress bool
7172
Timeout int

cmd/install.go

+51-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cmd
33
import (
44
"context"
55
"fmt"
6+
"github.com/AlecAivazis/survey/v2"
67
"github.com/linuxsuren/http-downloader/pkg/common"
78
"github.com/linuxsuren/http-downloader/pkg/exec"
89
"github.com/linuxsuren/http-downloader/pkg/installer"
@@ -28,13 +29,14 @@ func newInstallCmd(ctx context.Context) (cmd *cobra.Command) {
2829
Long: `Install a package from https://github.com/LinuxSuRen/hd-home
2930
Cannot find your desired package? Please run command: hd fetch --reset, then try it again`,
3031
Example: "hd install goget",
31-
Args: cobra.MinimumNArgs(1),
3232
PreRunE: opt.preRunE,
3333
RunE: opt.runE,
3434
}
3535

3636
flags := cmd.Flags()
3737
opt.addFlags(flags)
38+
flags.StringVarP(&opt.Category, "category", "", "",
39+
"The category of the potentials packages")
3840
flags.BoolVarP(&opt.ShowProgress, "show-progress", "", true, "If show the progress of download")
3941
flags.BoolVarP(&opt.AcceptPreRelease, "accept-preRelease", "", false,
4042
"If you accept preRelease as the binary asset from GitHub")
@@ -87,17 +89,24 @@ func (o *installOption) shouldInstall() (should, exist bool) {
8789
}
8890

8991
func (o *installOption) preRunE(cmd *cobra.Command, args []string) (err error) {
90-
o.tool = args[0]
92+
if len(args) > 0 {
93+
o.tool = args[0]
94+
}
95+
96+
if o.tool == "" && o.Category == "" {
97+
err = fmt.Errorf("tool or category name is requried")
98+
return
99+
}
91100

92101
// try to find if it's a native package
93102
o.nativePackage = os.HasPackage(o.tool)
94-
if !o.nativePackage {
103+
if !o.nativePackage && o.Category == "" {
95104
err = o.downloadOption.preRunE(cmd, args)
96105
}
97106
return
98107
}
99108

100-
func (o *installOption) runE(cmd *cobra.Command, args []string) (err error) {
109+
func (o *installOption) install(cmd *cobra.Command, args []string) (err error) {
101110
if should, exist := o.shouldInstall(); !should {
102111
if exist {
103112
cmd.Printf("%s is already exist\n", o.tool)
@@ -150,6 +159,44 @@ func (o *installOption) runE(cmd *cobra.Command, args []string) (err error) {
150159
return
151160
}
152161

162+
func (o *installOption) runE(cmd *cobra.Command, args []string) (err error) {
163+
if o.Category != "" {
164+
packages := installer.FindPackagesByCategory(o.Category)
165+
orgAndRepos := make([]string, len(packages))
166+
for i := range packages {
167+
orgAndRepos[i] = fmt.Sprintf("%s/%s", packages[i].Org, packages[i].Repo)
168+
}
169+
if len(orgAndRepos) == 0 {
170+
err = fmt.Errorf("cannot find any tools by category: %s", o.Category)
171+
return
172+
}
173+
174+
selector := &survey.MultiSelect{
175+
Message: "Select packages",
176+
Options: orgAndRepos,
177+
}
178+
179+
var choose []string
180+
if err = survey.AskOne(selector, &choose); err != nil {
181+
return
182+
}
183+
184+
for _, item := range choose {
185+
o.tool = item
186+
if err = o.downloadOption.preRunE(cmd, []string{item}); err != nil {
187+
return
188+
}
189+
if err = o.install(cmd, []string{item}); err != nil {
190+
return
191+
}
192+
o.Output = "" // TODO this field must be set to be empty for the next round, need a better solution here
193+
}
194+
} else {
195+
err = o.install(cmd, args)
196+
}
197+
return
198+
}
199+
153200
func (o *installOption) installFromSource() (err error) {
154201
if !o.Package.FromSource {
155202
err = fmt.Errorf("not support install it from source")

pkg/installer/check.go

+30
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/linuxsuren/http-downloader/pkg/os"
1313
"github.com/mitchellh/go-homedir"
1414
"gopkg.in/yaml.v2"
15+
"io/fs"
1516
"io/ioutil"
1617
"net/http"
1718
"net/url"
@@ -392,3 +393,32 @@ func getPackagingFormat(installer *Installer) string {
392393
func hasPackageSuffix(packageURL string) bool {
393394
return compress.IsSupport(path.Ext(packageURL))
394395
}
396+
397+
// FindPackagesByCategory returns the HDConfigs by category
398+
func FindPackagesByCategory(category string) (result []HDConfig) {
399+
configDir := sysos.ExpandEnv("$HOME/.config/hd-home/config/")
400+
_ = filepath.Walk(configDir, func(basepath string, info fs.FileInfo, err error) error {
401+
if !strings.HasSuffix(basepath, ".yml") {
402+
return nil
403+
}
404+
405+
if data, err := ioutil.ReadFile(basepath); err == nil {
406+
hdCfg := &HDConfig{}
407+
if err := yaml.Unmarshal(data, hdCfg); err == nil {
408+
orgAndRepo := strings.TrimPrefix(basepath, configDir)
409+
410+
hdCfg.Org = strings.Split(orgAndRepo, "/")[0]
411+
hdCfg.Repo = strings.TrimSuffix(strings.Split(orgAndRepo, "/")[1], ".yml")
412+
413+
for _, item := range hdCfg.Categories {
414+
if item == category {
415+
result = append(result, *hdCfg)
416+
break
417+
}
418+
}
419+
}
420+
}
421+
return nil
422+
})
423+
return
424+
}

pkg/installer/check_test.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func TestGetVersion(t *testing.T) {
1515
wantErr bool
1616
}{
1717
{
18-
name: "empty version, repo as default name",
18+
name: "empty version, Repo as default name",
1919
appInfo: "kubernetes-sigs/kustomize",
2020
verify: func(o *Installer, version string, t *testing.T) {
2121
assert.Equal(t, version, "latest")
@@ -93,7 +93,7 @@ func TestProviderURLParseNoConfig(t *testing.T) {
9393
wantErr bool
9494
}{
9595
{
96-
name: "empty version, repo as default name",
96+
name: "empty version, Repo as default name",
9797
packageURL: "orgtest/repotest",
9898
verify: func(o *Installer, packageURL string, t *testing.T) {
9999
expectURL := fmt.Sprintf(
@@ -180,14 +180,14 @@ func TestValidPackageSuffix(t *testing.T) {
180180
want bool
181181
}{
182182
{
183-
name: "empty version, repo as default name",
183+
name: "empty version, Repo as default name",
184184
args: args{
185185
"https://github.com/orgtest/repotest/releases/latest/download/repotest-%s-%s.%s",
186186
},
187187
want: true,
188188
},
189189
{
190-
name: "empty version, repo as default name",
190+
name: "empty version, Repo as default name",
191191
args: args{
192192
"https://github.com/orgtest/repotest/releases/latest/download/hello-%s-%s.%s",
193193
},
@@ -236,3 +236,8 @@ func TestValidPackageSuffix(t *testing.T) {
236236
})
237237
}
238238
}
239+
240+
func TestA(t *testing.T) {
241+
a := FindPackagesByCategory("k8s")
242+
fmt.Println(a)
243+
}

pkg/installer/process.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ func (o *Installer) OverWriteBinary(sourceFile, targetPath string) (err error) {
113113
}
114114

115115
func (o *Installer) extractFiles(tarFile, targetName string) (err error) {
116-
err = compress.GetCompressor(path.Ext(tarFile), o.AdditionBinaries).ExtractFiles(tarFile, targetName)
116+
compressor := compress.GetCompressor(path.Ext(tarFile), o.AdditionBinaries)
117+
if compressor == nil {
118+
err = fmt.Errorf("no compressor support for %s", tarFile)
119+
} else {
120+
err = compressor.ExtractFiles(tarFile, targetName)
121+
}
117122
return
118123
}

pkg/installer/types.go

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type PackagingFormat struct {
99
// HDConfig is the config of http-downloader
1010
type HDConfig struct {
1111
Name string `yaml:"Name"`
12+
Categories []string `yaml:"categories"`
1213
Filename string `yaml:"filename"`
1314
FormatOverrides PackagingFormat `yaml:"formatOverrides"`
1415
Binary string `yaml:"binary"`
@@ -26,6 +27,8 @@ type HDConfig struct {
2627
PreInstalls []CmdWithArgs `yaml:"preInstalls"`
2728
PostInstalls []CmdWithArgs `yaml:"postInstalls"`
2829
TestInstalls []CmdWithArgs `yaml:"testInstalls"`
30+
31+
Org, Repo string
2932
}
3033

3134
// CmdWithArgs is a command with arguments

0 commit comments

Comments
 (0)