diff --git a/cmd/get.go b/cmd/get.go index e945d38..35b20b6 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -4,8 +4,6 @@ import ( "bytes" "context" "fmt" - "github.com/linuxsuren/http-downloader/pkg/common" - "github.com/linuxsuren/http-downloader/pkg/log" "io" "io/fs" "net/http" @@ -16,6 +14,9 @@ import ( "strings" "sync" + "github.com/linuxsuren/http-downloader/pkg/common" + "github.com/linuxsuren/http-downloader/pkg/log" + "github.com/AlecAivazis/survey/v2" "github.com/linuxsuren/http-downloader/pkg/exec" "golang.org/x/net/html" @@ -25,6 +26,7 @@ import ( "github.com/linuxsuren/http-downloader/pkg/installer" "github.com/linuxsuren/http-downloader/pkg/net" "github.com/spf13/cobra" + "github.com/spf13/pflag" "github.com/spf13/viper" "gopkg.in/yaml.v3" ) @@ -43,6 +45,7 @@ func newGetCmd(ctx context.Context) (cmd *cobra.Command) { // set flags flags := cmd.Flags() opt.addFlags(flags) + opt.addPlatformFlags(flags) flags.StringVarP(&opt.Output, "output", "o", "", "Write output to instead of stdout.") flags.BoolVarP(&opt.AcceptPreRelease, "accept-preRelease", "", false, "If you accept preRelease as the binary asset from GitHub") @@ -63,8 +66,6 @@ func newGetCmd(ctx context.Context) (cmd *cobra.Command) { `Download file with multi-threads. It only works when its value is bigger than 1`) flags.BoolVarP(&opt.KeepPart, "keep-part", "", false, "If you want to keep the part files instead of deleting them") - flags.StringVarP(&opt.OS, "os", "", runtime.GOOS, "The OS of target binary file") - flags.StringVarP(&opt.Arch, "arch", "", runtime.GOARCH, "The arch of target binary file") flags.BoolVarP(&opt.PrintSchema, "print-schema", "", false, "Print the schema of HDConfig if the flag is true without other function") flags.BoolVarP(&opt.PrintVersion, "print-version", "", false, @@ -226,6 +227,11 @@ func (o *downloadOption) preRunE(cmd *cobra.Command, args []string) (err error) return } +func (o *downloadOption) addPlatformFlags(flags *pflag.FlagSet) { + flags.StringVarP(&o.OS, "os", "", runtime.GOOS, "The OS of target binary file") + flags.StringVarP(&o.Arch, "arch", "", runtime.GOARCH, "The arch of target binary file") +} + func findAnchor(n *html.Node) (items []string) { if n.Type == html.ElementNode && n.Data == "a" { for _, a := range n.Attr { @@ -295,8 +301,8 @@ func (o *downloadOption) runE(cmd *cobra.Command, args []string) (err error) { targetURL := o.URL if o.ProxyGitHub != "" { - targetURL = strings.Replace(targetURL, "github.com", fmt.Sprintf("%s/github.com", o.ProxyGitHub), 1) - targetURL = strings.Replace(targetURL, "raw.githubusercontent.com", fmt.Sprintf("%s/https://raw.githubusercontent.com", o.ProxyGitHub), 1) + targetURL = strings.Replace(targetURL, "https://github.com", fmt.Sprintf("https://%s/github.com", o.ProxyGitHub), 1) + targetURL = strings.Replace(targetURL, "https://raw.githubusercontent.com", fmt.Sprintf("https://%s/https://raw.githubusercontent.com", o.ProxyGitHub), 1) } logger.Printf("start to download from %s\n", targetURL) var suggestedFilenameAware net.SuggestedFilenameAware diff --git a/cmd/install.go b/cmd/install.go index d5ee37a..70ea6f2 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -3,6 +3,11 @@ package cmd import ( "context" "fmt" + "log" + sysos "os" + "path" + "strings" + "github.com/AlecAivazis/survey/v2" "github.com/linuxsuren/http-downloader/pkg/common" "github.com/linuxsuren/http-downloader/pkg/exec" @@ -11,11 +16,6 @@ import ( "github.com/linuxsuren/http-downloader/pkg/version" "github.com/spf13/cobra" "github.com/spf13/viper" - "log" - sysos "os" - "path" - "runtime" - "strings" ) // newInstallCmd returns the install command @@ -37,6 +37,7 @@ Cannot find your desired package? Please run command: hd fetch --reset, then try flags := cmd.Flags() opt.addFlags(flags) + opt.addPlatformFlags(flags) flags.StringVarP(&opt.Category, "category", "c", "", "The category of the potentials packages") flags.BoolVarP(&opt.ShowProgress, "show-progress", "", true, "If show the progress of download") @@ -63,8 +64,6 @@ Cannot find your desired package? Please run command: hd fetch --reset, then try flags.BoolVarP(&opt.NoProxy, "no-proxy", "", viper.GetBool("no-proxy"), "Indicate no HTTP proxy taken") flags.BoolVarP(&opt.KeepPart, "keep-part", "", false, "If you want to keep the part files instead of deleting them") - flags.StringVarP(&opt.OS, "os", "", runtime.GOOS, "The OS of target binary file") - flags.StringVarP(&opt.Arch, "arch", "", runtime.GOARCH, "The arch of target binary file") _ = cmd.RegisterFlagCompletionFunc("provider", ArrayCompletion(ProviderGitHub, ProviderGitee)) return @@ -151,8 +150,8 @@ func (o *installOption) install(cmd *cobra.Command, args []string) (err error) { var proxy map[string]string if o.ProxyGitHub != "" { proxy = map[string]string{ - "raw.githubusercontent.com": fmt.Sprintf("%s/https://raw.githubusercontent.com", o.ProxyGitHub), - "github.com": fmt.Sprintf("%s/https://github.com", o.ProxyGitHub), + "https://raw.githubusercontent.com": fmt.Sprintf("https://%s/https://raw.githubusercontent.com", o.ProxyGitHub), + "https://github.com": fmt.Sprintf("https://%s/https://github.com", o.ProxyGitHub), } } err = os.InstallWithProxy(args[0], proxy) diff --git a/cmd/search.go b/cmd/search.go index 400d3b3..f90cd9f 100644 --- a/cmd/search.go +++ b/cmd/search.go @@ -3,11 +3,12 @@ package cmd import ( "context" "fmt" + "io" + "github.com/linuxsuren/http-downloader/pkg/installer" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" - sysos "os" ) func newSearchCmd(context.Context) (cmd *cobra.Command) { @@ -43,14 +44,14 @@ Available proxy: gh.api.99988866.xyz, ghproxy.com Thanks to https://github.com/hunshcn/gh-proxy`) } -func (s *searchOption) runE(_ *cobra.Command, args []string) (err error) { - err = search(args[0], s.Fetch, s.fetcher) +func (s *searchOption) runE(c *cobra.Command, args []string) (err error) { + err = search(args[0], s.Fetch, s.fetcher, c.OutOrStdout()) return } -func search(keyword string, fetch bool, fetcher installer.Fetcher) (err error) { +func search(keyword string, fetch bool, fetcher installer.Fetcher, writer io.Writer) (err error) { if fetch { - if err = fetcher.FetchLatestRepo("", "", sysos.Stdout); err != nil { + if err = fetcher.FetchLatestRepo("", "", writer); err != nil { return } } @@ -62,7 +63,7 @@ func search(keyword string, fetch bool, fetcher installer.Fetcher) (err error) { result := installer.FindByKeyword(keyword, configDir) for _, item := range result { - fmt.Println(item) + fmt.Fprintln(writer, item) } return } diff --git a/cmd/search_test.go b/cmd/search_test.go index cca9e0c..74a43a1 100644 --- a/cmd/search_test.go +++ b/cmd/search_test.go @@ -1,25 +1,29 @@ package cmd import ( + "bytes" "context" "errors" - "github.com/linuxsuren/http-downloader/pkg/installer" - "github.com/stretchr/testify/assert" "os" "path" "testing" + + "github.com/linuxsuren/http-downloader/pkg/installer" + "github.com/stretchr/testify/assert" ) func Test_search(t *testing.T) { - err := search("keyword", true, &installer.FakeFetcher{}) + buf := &bytes.Buffer{} + err := search("keyword", true, &installer.FakeFetcher{}, buf) assert.Nil(t, err) + assert.Empty(t, buf.String()) // expect an error with GetConfigDir - err = search("", true, &installer.FakeFetcher{GetConfigDirErr: errors.New("fake")}) + err = search("", true, &installer.FakeFetcher{GetConfigDirErr: errors.New("fake")}, buf) assert.NotNil(t, err) // expect an error with FetchLatestRepo - err = search("", true, &installer.FakeFetcher{FetchLatestRepoErr: errors.New("fake")}) + err = search("", true, &installer.FakeFetcher{FetchLatestRepoErr: errors.New("fake")}, buf) assert.NotNil(t, err) tempDir, err := os.MkdirTemp("", "config") @@ -37,7 +41,7 @@ func Test_search(t *testing.T) { err = os.WriteFile(path.Join(orgDir, "fake.yml"), []byte{}, os.ModeAppend) assert.Nil(t, err) - err = search("repo", true, &installer.FakeFetcher{ConfigDir: tempDir}) + err = search("repo", true, &installer.FakeFetcher{ConfigDir: tempDir}, buf) assert.Nil(t, err) } diff --git a/pkg/installer/check.go b/pkg/installer/check.go index ef142e1..a994dab 100644 --- a/pkg/installer/check.go +++ b/pkg/installer/check.go @@ -439,6 +439,9 @@ func FindByKeyword(keyword, configDir string) (result []string) { result = append(result, path.Join(org, repo)) } } + + // find in the generic packages + result = append(result, os.SearchPackages(keyword)...) return } diff --git a/pkg/os/installer.go b/pkg/os/installer.go index e9df99d..33d2791 100644 --- a/pkg/os/installer.go +++ b/pkg/os/installer.go @@ -4,6 +4,7 @@ import ( "fmt" "path" "path/filepath" + "strings" "github.com/linuxsuren/http-downloader/pkg/exec" "github.com/linuxsuren/http-downloader/pkg/os/apt" @@ -69,6 +70,26 @@ func HasPackage(name string) bool { return false } +// SearchPackages searches the packages by keyword +func SearchPackages(keyword string) (pkgs []string) { + for key, pms := range defaultInstallerRegistry.installerMap { + if strings.Contains(key, keyword) { + var available bool + for _, pm := range pms { + if pm.Available() { + available = true + break + } + } + + if available { + pkgs = append(pkgs, key) + } + } + } + return +} + // InstallWithProxy installs a package with name func InstallWithProxy(name string, proxy map[string]string) (err error) { var installer core.Installer diff --git a/pkg/os/installer_test.go b/pkg/os/installer_test.go index 7fcb198..2f92e96 100644 --- a/pkg/os/installer_test.go +++ b/pkg/os/installer_test.go @@ -77,3 +77,12 @@ func TestWithFakeInstaller(t *testing.T) { err = Uninstall("fake-with-err") assert.NotNil(t, err) } + +func TestSearchPackages(t *testing.T) { + // currently, this function only support Linux + if runtime.GOOS != "linux" { + return + } + pkgs := SearchPackages("vim") + assert.NotEmpty(t, pkgs) +}