Skip to content

Commit

Permalink
Support to install tools by category (#189)
Browse files Browse the repository at this point in the history
  • Loading branch information
LinuxSuRen authored Dec 2, 2021
1 parent 183fe72 commit 8fc2c77
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 9 deletions.
1 change: 1 addition & 0 deletions cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type downloadOption struct {
searchOption

URL string
Category string
Output string
ShowProgress bool
Timeout int
Expand Down
55 changes: 51 additions & 4 deletions cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"context"
"fmt"
"github.com/AlecAivazis/survey/v2"
"github.com/linuxsuren/http-downloader/pkg/common"
"github.com/linuxsuren/http-downloader/pkg/exec"
"github.com/linuxsuren/http-downloader/pkg/installer"
Expand All @@ -28,13 +29,14 @@ func newInstallCmd(ctx context.Context) (cmd *cobra.Command) {
Long: `Install a package from https://github.com/LinuxSuRen/hd-home
Cannot find your desired package? Please run command: hd fetch --reset, then try it again`,
Example: "hd install goget",
Args: cobra.MinimumNArgs(1),
PreRunE: opt.preRunE,
RunE: opt.runE,
}

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

func (o *installOption) preRunE(cmd *cobra.Command, args []string) (err error) {
o.tool = args[0]
if len(args) > 0 {
o.tool = args[0]
}

if o.tool == "" && o.Category == "" {
err = fmt.Errorf("tool or category name is requried")
return
}

// try to find if it's a native package
o.nativePackage = os.HasPackage(o.tool)
if !o.nativePackage {
if !o.nativePackage && o.Category == "" {
err = o.downloadOption.preRunE(cmd, args)
}
return
}

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

func (o *installOption) runE(cmd *cobra.Command, args []string) (err error) {
if o.Category != "" {
packages := installer.FindPackagesByCategory(o.Category)
orgAndRepos := make([]string, len(packages))
for i := range packages {
orgAndRepos[i] = fmt.Sprintf("%s/%s", packages[i].Org, packages[i].Repo)
}
if len(orgAndRepos) == 0 {
err = fmt.Errorf("cannot find any tools by category: %s", o.Category)
return
}

selector := &survey.MultiSelect{
Message: "Select packages",
Options: orgAndRepos,
}

var choose []string
if err = survey.AskOne(selector, &choose); err != nil {
return
}

for _, item := range choose {
o.tool = item
if err = o.downloadOption.preRunE(cmd, []string{item}); err != nil {
return
}
if err = o.install(cmd, []string{item}); err != nil {
return
}
o.Output = "" // TODO this field must be set to be empty for the next round, need a better solution here
}
} else {
err = o.install(cmd, args)
}
return
}

func (o *installOption) installFromSource() (err error) {
if !o.Package.FromSource {
err = fmt.Errorf("not support install it from source")
Expand Down
30 changes: 30 additions & 0 deletions pkg/installer/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/linuxsuren/http-downloader/pkg/os"
"github.com/mitchellh/go-homedir"
"gopkg.in/yaml.v2"
"io/fs"
"io/ioutil"
"net/http"
"net/url"
Expand Down Expand Up @@ -392,3 +393,32 @@ func getPackagingFormat(installer *Installer) string {
func hasPackageSuffix(packageURL string) bool {
return compress.IsSupport(path.Ext(packageURL))
}

// FindPackagesByCategory returns the HDConfigs by category
func FindPackagesByCategory(category string) (result []HDConfig) {
configDir := sysos.ExpandEnv("$HOME/.config/hd-home/config/")
_ = filepath.Walk(configDir, func(basepath string, info fs.FileInfo, err error) error {
if !strings.HasSuffix(basepath, ".yml") {
return nil
}

if data, err := ioutil.ReadFile(basepath); err == nil {
hdCfg := &HDConfig{}
if err := yaml.Unmarshal(data, hdCfg); err == nil {
orgAndRepo := strings.TrimPrefix(basepath, configDir)

hdCfg.Org = strings.Split(orgAndRepo, "/")[0]
hdCfg.Repo = strings.TrimSuffix(strings.Split(orgAndRepo, "/")[1], ".yml")

for _, item := range hdCfg.Categories {
if item == category {
result = append(result, *hdCfg)
break
}
}
}
}
return nil
})
return
}
13 changes: 9 additions & 4 deletions pkg/installer/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestGetVersion(t *testing.T) {
wantErr bool
}{
{
name: "empty version, repo as default name",
name: "empty version, Repo as default name",
appInfo: "kubernetes-sigs/kustomize",
verify: func(o *Installer, version string, t *testing.T) {
assert.Equal(t, version, "latest")
Expand Down Expand Up @@ -93,7 +93,7 @@ func TestProviderURLParseNoConfig(t *testing.T) {
wantErr bool
}{
{
name: "empty version, repo as default name",
name: "empty version, Repo as default name",
packageURL: "orgtest/repotest",
verify: func(o *Installer, packageURL string, t *testing.T) {
expectURL := fmt.Sprintf(
Expand Down Expand Up @@ -180,14 +180,14 @@ func TestValidPackageSuffix(t *testing.T) {
want bool
}{
{
name: "empty version, repo as default name",
name: "empty version, Repo as default name",
args: args{
"https://github.com/orgtest/repotest/releases/latest/download/repotest-%s-%s.%s",
},
want: true,
},
{
name: "empty version, repo as default name",
name: "empty version, Repo as default name",
args: args{
"https://github.com/orgtest/repotest/releases/latest/download/hello-%s-%s.%s",
},
Expand Down Expand Up @@ -236,3 +236,8 @@ func TestValidPackageSuffix(t *testing.T) {
})
}
}

func TestA(t *testing.T) {
a := FindPackagesByCategory("k8s")
fmt.Println(a)
}
7 changes: 6 additions & 1 deletion pkg/installer/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ func (o *Installer) OverWriteBinary(sourceFile, targetPath string) (err error) {
}

func (o *Installer) extractFiles(tarFile, targetName string) (err error) {
err = compress.GetCompressor(path.Ext(tarFile), o.AdditionBinaries).ExtractFiles(tarFile, targetName)
compressor := compress.GetCompressor(path.Ext(tarFile), o.AdditionBinaries)
if compressor == nil {
err = fmt.Errorf("no compressor support for %s", tarFile)
} else {
err = compressor.ExtractFiles(tarFile, targetName)
}
return
}
3 changes: 3 additions & 0 deletions pkg/installer/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type PackagingFormat struct {
// HDConfig is the config of http-downloader
type HDConfig struct {
Name string `yaml:"Name"`
Categories []string `yaml:"categories"`
Filename string `yaml:"filename"`
FormatOverrides PackagingFormat `yaml:"formatOverrides"`
Binary string `yaml:"binary"`
Expand All @@ -26,6 +27,8 @@ type HDConfig struct {
PreInstalls []CmdWithArgs `yaml:"preInstalls"`
PostInstalls []CmdWithArgs `yaml:"postInstalls"`
TestInstalls []CmdWithArgs `yaml:"testInstalls"`

Org, Repo string
}

// CmdWithArgs is a command with arguments
Expand Down

0 comments on commit 8fc2c77

Please sign in to comment.