Skip to content

Commit

Permalink
feat: get versions from Go Proxy (#3269)
Browse files Browse the repository at this point in the history
* feat: get versions from Go Proxy

* fix: sort versions

* fix: fix a lint error

* fix: exclude pre-release versions

* fix: fix goproxy client

* fix: fix a lint error

* docs: update JSONSchema
  • Loading branch information
suzuki-shunsuke authored Nov 20, 2024
1 parent f4c85b2 commit e6c5325
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 3 deletions.
9 changes: 9 additions & 0 deletions json-schema/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@
"path": {
"type": "string"
},
"go_version_path": {
"type": "string"
},
"complete_windows_ext": {
"type": "boolean"
},
Expand Down Expand Up @@ -483,6 +486,9 @@
"version_prefix": {
"type": "string"
},
"go_version_path": {
"type": "string"
},
"rosetta2": {
"type": "boolean"
},
Expand Down Expand Up @@ -714,6 +720,9 @@
"zip"
]
},
"go_version_path": {
"type": "string"
},
"version_filter": {
"type": "string"
},
Expand Down
16 changes: 16 additions & 0 deletions pkg/config/registry/package_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type PackageInfo struct {
Format string `json:"format,omitempty" jsonschema:"example=tar.gz,example=raw,example=zip,example=dmg" yaml:",omitempty"`
VersionFilter string `yaml:"version_filter,omitempty" json:"version_filter,omitempty"`
VersionPrefix string `yaml:"version_prefix,omitempty" json:"version_prefix,omitempty"`
GoVersionPath string `yaml:"go_version_path,omitempty" json:"go_version_path,omitempty"`
Rosetta2 bool `yaml:",omitempty" json:"rosetta2,omitempty"`
WindowsARMEmulation bool `yaml:"windows_arm_emulation,omitempty" json:"windows_arm_emulation,omitempty"`
NoAsset bool `yaml:"no_asset,omitempty" json:"no_asset,omitempty"`
Expand Down Expand Up @@ -106,6 +107,7 @@ type VersionOverride struct {
Path string `yaml:",omitempty" json:"path,omitempty"`
URL string `yaml:",omitempty" json:"url,omitempty"`
Format string `yaml:",omitempty" json:"format,omitempty" jsonschema:"example=tar.gz,example=raw,example=zip"`
GoVersionPath *string `yaml:"go_version_path,omitempty" json:"go_version_path,omitempty"`
VersionFilter *string `yaml:"version_filter,omitempty" json:"version_filter,omitempty"`
VersionPrefix *string `yaml:"version_prefix,omitempty" json:"version_prefix,omitempty"`
VersionSource string `json:"version_source,omitempty" yaml:"version_source,omitempty"`
Expand Down Expand Up @@ -140,6 +142,7 @@ type Override struct {
Crate string `json:"crate,omitempty" yaml:",omitempty"`
URL string `yaml:",omitempty" json:"url,omitempty"`
Path string `yaml:",omitempty" json:"path,omitempty"`
GoVersionPath *string `yaml:"go_version_path,omitempty" json:"go_version_path,omitempty"`
CompleteWindowsExt *bool `json:"complete_windows_ext,omitempty" yaml:"complete_windows_ext,omitempty"`
WindowsExt string `json:"windows_ext,omitempty" yaml:"windows_ext,omitempty"`
AppendExt *bool `json:"append_ext,omitempty" yaml:"append_ext,omitempty"`
Expand Down Expand Up @@ -178,6 +181,7 @@ func (p *PackageInfo) Copy() *PackageInfo {
SupportedEnvs: p.SupportedEnvs,
VersionFilter: p.VersionFilter,
VersionPrefix: p.VersionPrefix,
GoVersionPath: p.GoVersionPath,
Rosetta2: p.Rosetta2,
WindowsARMEmulation: p.WindowsARMEmulation,
Aliases: p.Aliases,
Expand Down Expand Up @@ -205,22 +209,26 @@ func (p *PackageInfo) resetByPkgType(typ string) { //nolint:funlen
p.URL = ""
p.Path = ""
p.Crate = ""
p.GoVersionPath = ""
p.Cargo = nil
case PkgInfoTypeGitHubContent:
p.URL = ""
p.Asset = ""
p.Crate = ""
p.GoVersionPath = ""
p.Cargo = nil
case PkgInfoTypeGitHubArchive:
p.URL = ""
p.Path = ""
p.Asset = ""
p.Crate = ""
p.GoVersionPath = ""
p.Cargo = nil
p.Format = ""
case PkgInfoTypeHTTP:
p.Path = ""
p.Asset = ""
p.GoVersionPath = ""
case PkgInfoTypeGoInstall:
p.URL = ""
p.Asset = ""
Expand Down Expand Up @@ -265,6 +273,7 @@ func (p *PackageInfo) resetByPkgType(typ string) { //nolint:funlen
p.Rosetta2 = false
p.WindowsARMEmulation = false
p.AppendExt = nil
p.GoVersionPath = ""
}
}

Expand Down Expand Up @@ -319,6 +328,9 @@ func (p *PackageInfo) overrideVersion(child *VersionOverride) *PackageInfo { //n
if child.VersionPrefix != nil {
pkg.VersionPrefix = *child.VersionPrefix
}
if child.GoVersionPath != nil {
pkg.GoVersionPath = *child.GoVersionPath
}
if child.Rosetta2 != nil {
pkg.Rosetta2 = *child.Rosetta2
}
Expand Down Expand Up @@ -461,6 +473,10 @@ func (p *PackageInfo) OverrideByRuntime(rt *runtime.Runtime) { //nolint:cyclop,f
if ov.Vars != nil {
p.Vars = ov.Vars
}

if ov.GoVersionPath != nil {
p.GoVersionPath = *ov.GoVersionPath
}
}

func (p *PackageInfo) OverrideByBuild() {
Expand Down
11 changes: 11 additions & 0 deletions pkg/controller/wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import (
"github.com/aquaproj/aqua/v2/pkg/slsa"
"github.com/aquaproj/aqua/v2/pkg/unarchive"
"github.com/aquaproj/aqua/v2/pkg/versiongetter"
"github.com/aquaproj/aqua/v2/pkg/versiongetter/goproxy"

"github.com/google/wire"
"github.com/spf13/afero"
Expand Down Expand Up @@ -218,6 +219,11 @@ func InitializeGenerateCommandController(ctx context.Context, param *config.Para
versiongetter.NewCargo,
versiongetter.NewGitHubRelease,
versiongetter.NewGitHubTag,
versiongetter.NewGoGetter,
wire.NewSet(
goproxy.New,
wire.Bind(new(versiongetter.GoProxyClient), new(*goproxy.Client)),
),
)
return &generate.Controller{}
}
Expand Down Expand Up @@ -898,10 +904,15 @@ func InitializeUpdateCommandController(ctx context.Context, param *config.Param,
versiongetter.NewCargo,
versiongetter.NewGitHubRelease,
versiongetter.NewGitHubTag,
versiongetter.NewGoGetter,
wire.NewSet(
cargo.NewClient,
wire.Bind(new(versiongetter.CargoClient), new(*cargo.Client)),
),
wire.NewSet(
goproxy.New,
wire.Bind(new(versiongetter.GoProxyClient), new(*goproxy.Client)),
),
wire.NewSet(
which.New,
wire.Bind(new(update.WhichController), new(*which.Controller)),
Expand Down
9 changes: 7 additions & 2 deletions pkg/controller/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/versiongetter/fuzzy_getter.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type FuzzyFinder interface {
func (g *FuzzyGetter) Get(ctx context.Context, logE *logrus.Entry, pkg *registry.PackageInfo, currentVersion string, useFinder bool, limit int) string { //nolint:cyclop
filters, err := createFilters(pkg)
if err != nil {
logerr.WithError(logE, err).Warn("create filters")
return ""
}

Expand Down
7 changes: 6 additions & 1 deletion pkg/versiongetter/general.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ type GeneralVersionGetter struct {
cargo *CargoVersionGetter
ghTag *GitHubTagVersionGetter
ghRelease *GitHubReleaseVersionGetter
goGetter *GoGetter
}

func NewGeneralVersionGetter(cargo *CargoVersionGetter, ghTag *GitHubTagVersionGetter, ghRelease *GitHubReleaseVersionGetter) *GeneralVersionGetter {
func NewGeneralVersionGetter(cargo *CargoVersionGetter, ghTag *GitHubTagVersionGetter, ghRelease *GitHubReleaseVersionGetter, goGetter *GoGetter) *GeneralVersionGetter {
return &GeneralVersionGetter{
cargo: cargo,
ghTag: ghTag,
ghRelease: ghRelease,
goGetter: goGetter,
}
}

Expand All @@ -45,6 +47,9 @@ func (g *GeneralVersionGetter) get(pkg *registry.PackageInfo) VersionGetter {
if pkg.Type == "cargo" {
return g.cargo
}
if pkg.GoVersionPath != "" {
return g.goGetter
}
if g.ghTag == nil {
return nil
}
Expand Down
81 changes: 81 additions & 0 deletions pkg/versiongetter/go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package versiongetter

import (
"context"
"fmt"
"sort"

"github.com/aquaproj/aqua/v2/pkg/config/registry"
"github.com/aquaproj/aqua/v2/pkg/fuzzyfinder"
"github.com/hashicorp/go-version"
"github.com/sirupsen/logrus"
)

type GoGetter struct {
gc GoProxyClient
}

func NewGoGetter(gc GoProxyClient) *GoGetter {
return &GoGetter{
gc: gc,
}
}

type GoProxyClient interface {
List(ctx context.Context, path string) ([]string, error)
}

func (g *GoGetter) Get(ctx context.Context, logE *logrus.Entry, pkg *registry.PackageInfo, _ []*Filter) (string, error) { //nolint:cyclop
versions, err := g.gc.List(ctx, pkg.GoVersionPath)
if err != nil {
return "", fmt.Errorf("list versions: %w", err)
}
var latest *version.Version
var preLatest *version.Version
for _, vs := range versions {
v, err := version.NewSemver(vs)
if err != nil {
logE.WithError(err).WithField("version", vs).Warn("parse a version")
continue
}
if v.Prerelease() == "" && (latest == nil || v.GreaterThan(latest)) {
latest = v
continue
}
if v.Prerelease() != "" && (preLatest == nil || v.GreaterThan(preLatest)) {
preLatest = v
continue
}
}
if latest != nil {
return latest.Original(), nil
}
if preLatest != nil {
return preLatest.Original(), nil
}
return "", nil
}

func (g *GoGetter) List(ctx context.Context, logE *logrus.Entry, pkg *registry.PackageInfo, _ []*Filter, _ int) ([]*fuzzyfinder.Item, error) {
vs, err := g.gc.List(ctx, pkg.GoVersionPath)
if err != nil {
return nil, fmt.Errorf("list versions: %w", err)
}
versions := make(version.Collection, 0, len(vs))
for _, v := range vs {
v, err := version.NewSemver(v)
if err != nil {
logE.WithError(err).WithField("version", vs).Warn("parse a version")
continue
}
versions = append(versions, v)
}
sort.Sort(sort.Reverse(versions))
items := make([]*fuzzyfinder.Item, len(versions))
for i, version := range versions {
items[i] = &fuzzyfinder.Item{
Item: version.Original(),
}
}
return items, nil
}
43 changes: 43 additions & 0 deletions pkg/versiongetter/goproxy/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package goproxy

import (
"context"
"fmt"
"io"
"net/http"
"strings"
)

type Client struct {
client *http.Client
}

func New(client *http.Client) *Client {
return &Client{
client: client,
}
}

func (c *Client) List(ctx context.Context, path string) ([]string, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://proxy.golang.org/%s/@v/list", path), nil)
if err != nil {
return nil, fmt.Errorf("create a http request: %w", err)
}
resp, err := c.client.Do(req)
if err != nil {
return nil, fmt.Errorf("send a http request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read a response body: %w", err)
}
s := strings.TrimSpace(string(b))
if s == "" {
return nil, nil
}
return strings.Split(s, "\n"), nil
}

0 comments on commit e6c5325

Please sign in to comment.