From 9e6e36efa3b9254662e9571a23b1724ee73b1479 Mon Sep 17 00:00:00 2001 From: Christoph Witzko <github@christophwitzko.com> Date: Wed, 1 Feb 2023 22:41:12 +0100 Subject: [PATCH] feat(registry): add single plugin fetching --- pkg/plugin/discovery/discovery.go | 61 ++++++++++++++++--- .../discovery/resolver/registry/registry.go | 61 +++++++++++++++++++ .../discovery/resolver/registryV1/registry.go | 2 +- pkg/plugin/discovery/resolver/resolver.go | 9 +++ 4 files changed, 123 insertions(+), 10 deletions(-) diff --git a/pkg/plugin/discovery/discovery.go b/pkg/plugin/discovery/discovery.go index 496debe..0b4e887 100644 --- a/pkg/plugin/discovery/discovery.go +++ b/pkg/plugin/discovery/discovery.go @@ -65,26 +65,69 @@ func (d *Discovery) fetchPlugin(pluginInfo *plugin.Info) (string, error) { return downloadPlugin(pluginInfo, downloadInfo, d.config.ShowProgress) } -func (d *Discovery) FindPlugin(t, name string) (*plugin.Info, error) { - pInfo, err := plugin.GetPluginInfo(t, name) - if err != nil { - return nil, err - } +func (d *Discovery) IsBatchResolver(resolverName string) bool { + _, ok := d.resolvers[resolverName].(resolver.BatchResolver) + return ok +} - err = setAndEnsurePluginPath(pInfo) +func (d *Discovery) FindPluginByPluginInfo(pInfo *plugin.Info) error { + err := setAndEnsurePluginPath(pInfo) if err != nil { - return nil, err + return err } binPath, err := findPluginLocally(pInfo) if errors.Is(err, ErrPluginNotFound) { binPath, err = d.fetchPlugin(pInfo) if err != nil { - return nil, err + return err } } else if err != nil { - return nil, err + return err } pInfo.BinPath = binPath + return nil +} + +func (d *Discovery) FindPlugin(t, name string) (*plugin.Info, error) { + pInfo, err := plugin.GetPluginInfo(t, name) + if err != nil { + return nil, err + } + err = d.FindPluginByPluginInfo(pInfo) + if err != nil { + return nil, err + } return pInfo, nil } + +func (d *Discovery) FindPluginsWithBatchResolver(resolverName string, pInfos []*plugin.Info) error { + if !d.IsBatchResolver(resolverName) { + return fmt.Errorf("resolver %s does not support batch resolving", resolverName) + } + missingPlugins := make([]*plugin.Info, 0) + for _, pInfo := range pInfos { + err := setAndEnsurePluginPath(pInfo) + if err != nil { + return err + } + + binPath, err := findPluginLocally(pInfo) + if errors.Is(err, ErrPluginNotFound) { + missingPlugins = append(missingPlugins, pInfo) + continue + } else if err != nil { + return err + } + pInfo.BinPath = binPath + } + + batchResolver := d.resolvers[resolverName].(resolver.BatchResolver) + batchDownloadInfo, err := batchResolver.BatchResolvePlugins(missingPlugins) + if err != nil { + return err + } + // TODO + _ = batchDownloadInfo + return nil +} diff --git a/pkg/plugin/discovery/resolver/registry/registry.go b/pkg/plugin/discovery/resolver/registry/registry.go index 6e28c08..28d3d17 100644 --- a/pkg/plugin/discovery/resolver/registry/registry.go +++ b/pkg/plugin/discovery/resolver/registry/registry.go @@ -1,8 +1,12 @@ package registry import ( + "context" "fmt" + "runtime" + "sort" + "github.com/Masterminds/semver/v3" "github.com/go-semantic-release/plugin-registry/pkg/client" "github.com/go-semantic-release/semantic-release/v2/pkg/plugin" "github.com/go-semantic-release/semantic-release/v2/pkg/plugin/discovery/resolver" @@ -21,6 +25,63 @@ func NewResolver() *Resolver { } func (r *Resolver) ResolvePlugin(pluginInfo *plugin.Info) (*resolver.PluginDownloadInfo, error) { + getPluginRes, err := r.client.GetPlugin(context.Background(), pluginInfo.ShortNormalizedName) + if err != nil { + return nil, err + } + + osArch := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) + if pluginInfo.Constraint == nil { + foundAsset := getPluginRes.LatestRelease.Assets[osArch] + if foundAsset == nil { + return nil, fmt.Errorf("a matching plugin was not found for %s/%s", runtime.GOOS, runtime.GOARCH) + } + return &resolver.PluginDownloadInfo{ + URL: foundAsset.URL, + Checksum: foundAsset.Checksum, + FileName: foundAsset.FileName, + Version: getPluginRes.LatestRelease.Version, + }, nil + } + + foundVersion := "" + versions := make(semver.Collection, 0) + for _, v := range getPluginRes.Versions { + pv, sErr := semver.NewVersion(v) + if sErr != nil { + return nil, sErr + } + versions = append(versions, pv) + } + sort.Sort(sort.Reverse(versions)) + for _, v := range versions { + if pluginInfo.Constraint.Check(v) { + foundVersion = v.String() + break + } + } + if foundVersion == "" { + return nil, fmt.Errorf("no matching version was found") + } + + pluginRelease, err := r.client.GetPluginRelease(context.Background(), pluginInfo.ShortNormalizedName, foundVersion) + if err != nil { + return nil, err + } + foundAsset := pluginRelease.Assets[osArch] + if foundAsset == nil { + return nil, fmt.Errorf("a matching plugin was not found for %s/%s", runtime.GOOS, runtime.GOARCH) + } + + return &resolver.PluginDownloadInfo{ + URL: foundAsset.URL, + Checksum: foundAsset.Checksum, + FileName: foundAsset.FileName, + Version: getPluginRes.LatestRelease.Version, + }, nil +} + +func (r *Resolver) BatchResolvePlugins(pluginInfos []*plugin.Info) (*resolver.BatchPluginDownloadInfo, error) { return nil, fmt.Errorf("not implemented") } diff --git a/pkg/plugin/discovery/resolver/registryV1/registry.go b/pkg/plugin/discovery/resolver/registryV1/registry.go index 470ae66..d30e89d 100644 --- a/pkg/plugin/discovery/resolver/registryV1/registry.go +++ b/pkg/plugin/discovery/resolver/registryV1/registry.go @@ -18,7 +18,7 @@ func NewResolver() *Resolver { } func (r *Resolver) ResolvePlugin(pluginInfo *plugin.Info) (*resolver.PluginDownloadInfo, error) { - pluginAPIRes, err := getPluginInfo(pluginInfo.NormalizedName) + pluginAPIRes, err := getPluginInfo(pluginInfo.ShortNormalizedName) if err != nil { return nil, err } diff --git a/pkg/plugin/discovery/resolver/resolver.go b/pkg/plugin/discovery/resolver/resolver.go index 947f8f1..5a1b93b 100644 --- a/pkg/plugin/discovery/resolver/resolver.go +++ b/pkg/plugin/discovery/resolver/resolver.go @@ -9,7 +9,16 @@ type PluginDownloadInfo struct { Version string } +type BatchPluginDownloadInfo struct { + URL string + Checksum string +} + type Resolver interface { ResolvePlugin(*plugin.Info) (*PluginDownloadInfo, error) Names() []string } + +type BatchResolver interface { + BatchResolvePlugins([]*plugin.Info) (*BatchPluginDownloadInfo, error) +} -- GitLab