diff --git a/cmd/commands/add.go b/cmd/commands/add.go index e600d77b..937e3201 100644 --- a/cmd/commands/add.go +++ b/cmd/commands/add.go @@ -17,7 +17,8 @@ package commands import ( - "errors" + "fmt" + "github.com/pterm/pterm" "github.com/urfave/cli/v2" "github.com/version-fox/vfox/internal" ) @@ -43,29 +44,22 @@ var Add = &cli.Command{ // addCmd is the command to add a plugin of sdk func addCmd(ctx *cli.Context) error { args := ctx.Args() - var errStr = "" - var source = "" - var alias = "" - var err error - - if args.Len() == 1 { - source = ctx.String("source") - alias = ctx.String("alias") - } manager := internal.NewSdkManager() - for _, sdkName := range args.Slice() { - err = manager.Add(sdkName, source, alias) - if err != nil { - errStr += err.Error() + "\r\n" - continue + defer manager.Close() + + // multiple plugins + if args.Len() > 1 { + for index, sdkName := range args.Slice() { + pterm.Printf("[%s/%d]: Adding %s plugin...\n", pterm.Green(index+1), args.Len(), pterm.Green(sdkName)) + if err := manager.Add(sdkName, "", ""); err != nil { + pterm.Println(fmt.Sprintf("Add plugin(%s) failed: %s", pterm.Red(sdkName), err.Error())) + } } + return nil + } else { + source := ctx.String("source") + alias := ctx.String("alias") + return manager.Add(args.First(), source, alias) } - manager.Close() - if errStr != "" { - err = errors.New(errStr) - return err - } - - return nil } diff --git a/internal/manager.go b/internal/manager.go index 9173d318..2c78556c 100644 --- a/internal/manager.go +++ b/internal/manager.go @@ -384,6 +384,24 @@ func (m *Manager) downloadPlugin(downloadUrl string) (string, error) { return path, nil } +func (m *Manager) pluginExist(name, alias string) bool { + pname := name + if len(alias) > 0 { + pname = alias + } + return util.FileExists(filepath.Join(m.PathMeta.PluginPath, pname)) +} + +// Add a plugin to plugin home directory +// 1. If the plugin is an official plugin, fetch the plugin manifest from the registry. +// 2. If the plugin is a custom plugin, install the plugin from the specified URL. +// 3. Validate the plugin and install it to the plugin home directory. +// examples: +// +// vfox add nodejs +// vfox add --alias node nodejs +// vfox add --source /path/to/plugin.zip +// vfox add --source /path/to/plugin.zip --alias node [nodejs] func (m *Manager) Add(pluginName, url, alias string) error { // For compatibility with older versions of plugin names / if strings.Contains(pluginName, "/") { @@ -394,11 +412,14 @@ func (m *Manager) Add(pluginName, url, alias string) error { if len(alias) > 0 { pname = alias } - installPath := filepath.Join(m.PathMeta.PluginPath, pname) - if util.FileExists(installPath) { - return fmt.Errorf("plugin named %s already exists", pname) + var installPath string + // first quick check. + if pname != "" { + installPath = filepath.Join(m.PathMeta.PluginPath, pname) + if util.FileExists(installPath) { + return fmt.Errorf("plugin named %s already exists", pname) + } } - // official plugin if len(url) == 0 { fmt.Printf("Fetching %s manifest... \n", pterm.Green(pluginName)) @@ -416,6 +437,14 @@ func (m *Manager) Add(pluginName, url, alias string) error { _ = os.RemoveAll(tempPlugin.Path) tempPlugin.Close() }() + // check plugin exist again as the plugin may be from custom source without plugin name and alias. + if pname == "" { + pname = tempPlugin.Name + installPath = filepath.Join(m.PathMeta.PluginPath, pname) + if util.FileExists(installPath) { + return fmt.Errorf("plugin named %s already exists", pname) + } + } if err = os.Rename(tempPlugin.Path, installPath); err != nil { return fmt.Errorf("install plugin error: %w", err) }