From 9746cf65bf83d3ee7c61814b8f27e91cb15a13b6 Mon Sep 17 00:00:00 2001
From: Christoph Witzko <github@christophwitzko.com>
Date: Thu, 2 Feb 2023 14:12:06 +0100
Subject: [PATCH] feat: add plugin resolver options

---
 cmd/semantic-release/main.go                  | 14 ++++++-----
 pkg/config/config.go                          | 10 +++++++-
 pkg/plugin/discovery/discovery.go             |  6 ++++-
 pkg/plugin/discovery/download.go              |  2 +-
 .../discovery/resolver/registry/registry.go   | 17 +++++++++----
 .../discovery/resolver/registryV1/api.go      |  6 ++---
 .../discovery/resolver/registryV1/registry.go | 24 +++++++++++++++----
 pkg/plugin/discovery/resolver/resolver.go     |  1 +
 8 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/cmd/semantic-release/main.go b/cmd/semantic-release/main.go
index ec75214..22c67d4 100644
--- a/cmd/semantic-release/main.go
+++ b/cmd/semantic-release/main.go
@@ -107,12 +107,14 @@ func cliHandler(cmd *cobra.Command, args []string) {
 		return
 	}
 
-	ok, _, err := pluginManager.PrefetchAllPluginsIfBatchIsPossible()
-	if err != nil {
-		logger.Printf("warning: failed to prefetch plugins: %v", err)
-	}
-	if ok {
-		logger.Println("all plugins were prefetched")
+	if !conf.PluginResolverDisableBatchPrefetch {
+		ok, _, pErr := pluginManager.PrefetchAllPluginsIfBatchIsPossible()
+		if pErr != nil {
+			logger.Printf("warning: failed to prefetch plugins: %v", pErr)
+		}
+		if ok {
+			logger.Println("all plugins were prefetched!")
+		}
 	}
 
 	ci, err := pluginManager.GetCICondition()
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 8c37b89..ea4d8b4 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -41,6 +41,8 @@ type Config struct {
 	ShowProgress                          bool
 	AllowMaintainedVersionOnDefaultBranch bool
 	PluginResolver                        string
+	PluginResolverEndpoint                string
+	PluginResolverDisableBatchPrefetch    bool
 }
 
 func mustGetString(cmd *cobra.Command, name string) string {
@@ -133,6 +135,8 @@ func NewConfig(cmd *cobra.Command) (*Config, error) {
 		ShowProgress:                          mustGetBool(cmd, "show-progress"),
 		AllowMaintainedVersionOnDefaultBranch: mustGetBool(cmd, "allow-maintained-version-on-default-branch"),
 		PluginResolver:                        viper.GetString("pluginResolver"),
+		PluginResolverEndpoint:                viper.GetString("pluginResolverEndpoint"),
+		PluginResolverDisableBatchPrefetch:    viper.GetBool("pluginResolverDisableBatchPrefetch"),
 	}
 	return conf, nil
 }
@@ -193,7 +197,9 @@ func SetFlags(cmd *cobra.Command) {
 	cmd.Flags().Bool("show-progress", false, "shows the plugin download progress")
 	cmd.Flags().String("config", "", "config file (default is .semrelrc)")
 	cmd.Flags().Bool("allow-maintained-version-on-default-branch", false, "allow configuring the maintained version on the default branch")
-	cmd.Flags().String("plugin-resolver", "registry", "which resolver should be used to resolve plugins (registry or github)")
+	cmd.Flags().String("plugin-resolver", "registry-v1", "which resolver should be used to resolve plugins (registry-v1, registry-v2 or github)")
+	cmd.Flags().Bool("plugin-resolver-disable-batch-prefetch", false, "plugins should not be batch prefetched using the registry")
+	cmd.Flags().String("plugin-resolver-endpoint", "", "explicitly specify the resolver endpoint that should be used for resolving the plugin dependencies")
 	cmd.Flags().SortFlags = true
 
 	must(viper.BindPFlag("maintainedVersion", cmd.Flags().Lookup("maintained-version")))
@@ -208,6 +214,8 @@ func SetFlags(cmd *cobra.Command) {
 
 	must(viper.BindPFlag("pluginResolver", cmd.Flags().Lookup("plugin-resolver")))
 	must(viper.BindEnv("pluginResolver", "SEMREL_PLUGIN_RESOLVER"))
+	must(viper.BindPFlag("pluginResolverDisableBatchPrefetch", cmd.Flags().Lookup("plugin-resolver-disable-batch-prefetch")))
+	must(viper.BindPFlag("pluginResolverEndpoint", cmd.Flags().Lookup("plugin-resolver-endpoint")))
 }
 
 func InitConfig(cmd *cobra.Command) error {
diff --git a/pkg/plugin/discovery/discovery.go b/pkg/plugin/discovery/discovery.go
index dc597de..2efed87 100644
--- a/pkg/plugin/discovery/discovery.go
+++ b/pkg/plugin/discovery/discovery.go
@@ -34,7 +34,11 @@ func loadResolvers(resolvers ...resolver.Resolver) (map[string]resolver.Resolver
 }
 
 func New(config *config.Config) (*Discovery, error) {
-	resolvers, err := loadResolvers(registryV1.NewResolver(), github.NewResolver(), registry.NewResolver())
+	resolvers, err := loadResolvers(
+		registry.NewResolver(config.PluginResolverEndpoint),
+		registryV1.NewResolver(config.PluginResolverEndpoint),
+		github.NewResolver(),
+	)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/plugin/discovery/download.go b/pkg/plugin/discovery/download.go
index f54d568..f1a38b4 100644
--- a/pkg/plugin/discovery/download.go
+++ b/pkg/plugin/discovery/download.go
@@ -144,7 +144,7 @@ func downloadBatchPlugins(pluginInfos []*plugin.Info, downloadInfo *resolver.Bat
 
 	res := grab.DefaultClient.Do(req)
 	if showProgress {
-		showDownloadProgressBar("batched-plugins", res)
+		showDownloadProgressBar("batched-plugins.tar.gz", res)
 	}
 	err = res.Err()
 	if err != nil {
diff --git a/pkg/plugin/discovery/resolver/registry/registry.go b/pkg/plugin/discovery/resolver/registry/registry.go
index 83ac036..63bfbab 100644
--- a/pkg/plugin/discovery/resolver/registry/registry.go
+++ b/pkg/plugin/discovery/resolver/registry/registry.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"runtime"
 	"sort"
+	"strings"
 
 	"github.com/Masterminds/semver/v3"
 	"github.com/go-semantic-release/plugin-registry/pkg/client"
@@ -13,15 +14,22 @@ import (
 	"github.com/go-semantic-release/semantic-release/v2/pkg/plugin/discovery/resolver"
 )
 
-const DefaultEndpoint = "https://registry-staging.go-semantic-release.xyz/api/v2"
+const DefaultEndpoint = "https://registry.go-semantic-release.xyz/api/v2"
 
 type Resolver struct {
 	client *client.Client
 }
 
-func NewResolver() *Resolver {
+func NewResolver(endpoint string) *Resolver {
+	if endpoint == "" {
+		endpoint = DefaultEndpoint
+	}
+	endpoint = strings.TrimSuffix(endpoint, "/")
+	if !strings.HasSuffix(endpoint, "/api/v2") {
+		endpoint = fmt.Sprintf("%s/api/v2", endpoint)
+	}
 	return &Resolver{
-		client: client.New(DefaultEndpoint),
+		client: client.New(endpoint),
 	}
 }
 
@@ -110,6 +118,5 @@ func (r *Resolver) BatchResolvePlugins(pluginInfos []*plugin.Info) (*resolver.Ba
 }
 
 func (r *Resolver) Names() []string {
-	// TODO: this should be registry when the registry is ready
-	return []string{"registry-beta"}
+	return []string{"registry", "registry-v2"}
 }
diff --git a/pkg/plugin/discovery/resolver/registryV1/api.go b/pkg/plugin/discovery/resolver/registryV1/api.go
index 7ece18b..2ce8dbc 100644
--- a/pkg/plugin/discovery/resolver/registryV1/api.go
+++ b/pkg/plugin/discovery/resolver/registryV1/api.go
@@ -9,8 +9,6 @@ import (
 	"time"
 )
 
-const PluginAPI = "https://plugins.go-semantic-release.xyz/api/v1"
-
 type apiPluginAsset struct {
 	FileName string
 	URL      string
@@ -38,8 +36,8 @@ type apiPlugin struct {
 	Versions      map[string]*apiPluginRelease
 }
 
-func getPluginInfo(name string) (*apiPlugin, error) {
-	res, err := http.Get(fmt.Sprintf("%s/plugins/%s.json", PluginAPI, name))
+func getPluginInfo(endpoint, name string) (*apiPlugin, error) {
+	res, err := http.Get(fmt.Sprintf("%s/plugins/%s.json", endpoint, name))
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/plugin/discovery/resolver/registryV1/registry.go b/pkg/plugin/discovery/resolver/registryV1/registry.go
index d30e89d..aa6588f 100644
--- a/pkg/plugin/discovery/resolver/registryV1/registry.go
+++ b/pkg/plugin/discovery/resolver/registryV1/registry.go
@@ -5,20 +5,34 @@ import (
 	"fmt"
 	"runtime"
 	"sort"
+	"strings"
 
 	"github.com/Masterminds/semver/v3"
 	"github.com/go-semantic-release/semantic-release/v2/pkg/plugin"
 	"github.com/go-semantic-release/semantic-release/v2/pkg/plugin/discovery/resolver"
 )
 
-type Resolver struct{}
+const DefaultEndpoint = "https://plugins.go-semantic-release.xyz/api/v1"
 
-func NewResolver() *Resolver {
-	return &Resolver{}
+type Resolver struct {
+	endpoint string
+}
+
+func NewResolver(endpoint string) *Resolver {
+	if endpoint == "" {
+		endpoint = DefaultEndpoint
+	}
+	endpoint = strings.TrimSuffix(endpoint, "/")
+	if !strings.HasSuffix(endpoint, "/api/v1") {
+		endpoint = fmt.Sprintf("%s/api/v1", endpoint)
+	}
+	return &Resolver{
+		endpoint: endpoint,
+	}
 }
 
 func (r *Resolver) ResolvePlugin(pluginInfo *plugin.Info) (*resolver.PluginDownloadInfo, error) {
-	pluginAPIRes, err := getPluginInfo(pluginInfo.ShortNormalizedName)
+	pluginAPIRes, err := getPluginInfo(r.endpoint, pluginInfo.ShortNormalizedName)
 	if err != nil {
 		return nil, err
 	}
@@ -61,5 +75,5 @@ func (r *Resolver) ResolvePlugin(pluginInfo *plugin.Info) (*resolver.PluginDownl
 }
 
 func (r *Resolver) Names() []string {
-	return []string{"registry"}
+	return []string{"registry-v1"}
 }
diff --git a/pkg/plugin/discovery/resolver/resolver.go b/pkg/plugin/discovery/resolver/resolver.go
index 5a1b93b..3494a51 100644
--- a/pkg/plugin/discovery/resolver/resolver.go
+++ b/pkg/plugin/discovery/resolver/resolver.go
@@ -20,5 +20,6 @@ type Resolver interface {
 }
 
 type BatchResolver interface {
+	// BatchResolvePlugins resolves a list of plugins and returns a single URL to download all plugins as tgz archive.
 	BatchResolvePlugins([]*plugin.Info) (*BatchPluginDownloadInfo, error)
 }
-- 
GitLab