@@ -3,6 +3,7 @@ package cmd
33import (
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
2930Cannot 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
8991func (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+
153200func (o * installOption ) installFromSource () (err error ) {
154201 if ! o .Package .FromSource {
155202 err = fmt .Errorf ("not support install it from source" )
0 commit comments