Skip to content

Commit

Permalink
asset/download: support arch aliases
Browse files Browse the repository at this point in the history
Some assets have multiple ways to refer to the same arch.

e.g: amd64 -> x86_64

To support this, users can add fallback arch to the Downloader.
  • Loading branch information
joshi4 committed Jun 4, 2024
1 parent c0b0ac7 commit f8be648
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
47 changes: 39 additions & 8 deletions release/asset/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ type Info struct {
}

type downloader struct {
os string
arch string
executablePath string
os string
arch string
lookupArchFallback map[string]string
executablePath string
}

var _ Downloader = (*downloader)(nil)
Expand All @@ -49,11 +50,18 @@ func WithArch(arch string) AssetDownloadOpt {
}
}

func WithLookupArchFallback(lookupArchFallback map[string]string) AssetDownloadOpt {
return func(d *downloader) {
d.lookupArchFallback = lookupArchFallback
}
}

func NewAssetDownloader(executablePath string, opts ...AssetDownloadOpt) Downloader {
d := &downloader{
os: runtime.GOOS,
arch: runtime.GOARCH,
executablePath: executablePath,
os: runtime.GOOS,
arch: runtime.GOARCH,
executablePath: executablePath,
lookupArchFallback: map[string]string{},
}
for _, opt := range opts {
opt(d)
Expand All @@ -66,12 +74,35 @@ var ErrNoAsset = errors.New("no asset found")
func (d *downloader) DownloadAsset(ctx context.Context, assets []release.Asset) (*Info, cleanupFn, error) {
// iterate through the assets and find the one that matches the os and arch
suffix := d.os + "_" + d.arch
asset, found := d.assetForSuffix(assets, suffix)
if found {
return d.downloadAsset(ctx, asset.BrowserDownloadURL)
}
// if asset not found, try a fallback. e.g amd64 -> x86_64
if d.lookupArchFallback == nil || len(d.lookupArchFallback) == 0 {
return nil, nil, fmt.Errorf("%w: os:%s arch:%s", ErrNoAsset, d.os, d.arch)
}

fallbackArch, ok := d.lookupArchFallback[d.arch]
if !ok {
return nil, nil, fmt.Errorf("%w: os:%s arch:%s", ErrNoAsset, d.os, d.arch)
}

fallbackSuffix := d.os + "_" + fallbackArch
asset, found = d.assetForSuffix(assets, fallbackSuffix)
if found {
return d.downloadAsset(ctx, asset.BrowserDownloadURL)
}
return nil, nil, fmt.Errorf("%w: os:%s arch:%s", ErrNoAsset, d.os, d.arch)
}

func (d *downloader) assetForSuffix(assets []release.Asset, suffix string) (release.Asset, bool) {
for _, asset := range assets {
if strings.HasSuffix(asset.BrowserDownloadURL, suffix) {
return d.downloadAsset(ctx, asset.BrowserDownloadURL)
return asset, true
}
}
return nil, nil, fmt.Errorf("%w: os:%s arch:%s", ErrNoAsset, d.os, d.arch)
return release.Asset{}, false
}

func (d *downloader) downloadAsset(ctx context.Context, url string) (*Info, cleanupFn, error) {
Expand Down
23 changes: 23 additions & 0 deletions release/asset/download_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,27 @@ func TestAssetDownloader(t *testing.T) {
assert.NoFileExists(t, tmpFile)
})
})
t.Run("VerifyFallback", func(t *testing.T) {
srv := setupTestServer(t, http.HandlerFunc(downloadDataHandler))
ctx := context.Background()
t.Run("DownloadFailsWithoutFallback", func(t *testing.T) {
downloader := NewAssetDownloader(executablePath, WithOS("os"), WithArch("amd64"))
asset, cleanupFn, err := downloader.DownloadAsset(ctx, []release.Asset{
{BrowserDownloadURL: srv.URL + "/download_os_x86_64"},
})
assert.ErrorIs(t, err, ErrNoAsset)
assert.Nil(t, asset)
assert.Nil(t, cleanupFn)
})
t.Run("DownloadSucceedsWithFallback", func(t *testing.T) {
downloader := NewAssetDownloader(executablePath, WithOS("os"), WithArch("amd64"), WithLookupArchFallback(map[string]string{"amd64": "x86_64"}))
asset, cleanupFn, err := downloader.DownloadAsset(ctx, []release.Asset{
{BrowserDownloadURL: srv.URL + "/download_os_x86_64"},
})
assert.NoError(t, err)
assert.NotNil(t, asset)
assert.NotNil(t, cleanupFn)
assert.Equal(t, downloadDataChecksum, asset.Checksum)
})
})
}

0 comments on commit f8be648

Please sign in to comment.