Skip to content

Commit

Permalink
Merge pull request #55 from hashicorp/alisdair/sourcebundle-client-ex…
Browse files Browse the repository at this point in the history
…tensibility

sourcebundle: Improve client extensibility
  • Loading branch information
alisdair authored Feb 2, 2024
2 parents 0480d9e + ad514a9 commit 0ba92f7
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 30 deletions.
13 changes: 7 additions & 6 deletions sourcebundle/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,14 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour
reqCtx = ctx
}

vs, err := b.registryClient.ModulePackageVersions(reqCtx, pkgAddr)
resp, err := b.registryClient.ModulePackageVersions(reqCtx, pkgAddr)
if err != nil {
if cb := trace.RegistryPackageVersionsFailure; cb != nil {
cb(reqCtx, pkgAddr, err)
}
return sourceaddrs.RemoteSource{}, fmt.Errorf("failed to query available versions for %s: %w", pkgAddr, err)
}
vs := resp.Versions
vs.Sort()
availableVersions = vs
b.registryPackageVersions[pkgAddr] = availableVersions
Expand Down Expand Up @@ -391,14 +392,14 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour
reqCtx = ctx
}

sa, err := b.registryClient.ModulePackageSourceAddr(reqCtx, pkgAddr, selectedVersion)
resp, err := b.registryClient.ModulePackageSourceAddr(reqCtx, pkgAddr, selectedVersion)
if err != nil {
if cb := trace.RegistryPackageSourceFailure; cb != nil {
cb(reqCtx, pkgAddr, selectedVersion, err)
}
return sourceaddrs.RemoteSource{}, fmt.Errorf("failed to find real source address for %s %s: %w", pkgAddr, selectedVersion, err)
}
realSourceAddr = sa
realSourceAddr = resp.SourceAddr
b.resolvedRegistry[pkgVer] = realSourceAddr
if cb := trace.RegistryPackageSourceSuccess; cb != nil {
cb(reqCtx, pkgAddr, selectedVersion, realSourceAddr)
Expand Down Expand Up @@ -459,13 +460,13 @@ func (b *Builder) ensureRemotePackage(ctx context.Context, pkgAddr sourceaddrs.R
return "", fmt.Errorf("failed to create new package directory: %w", err)
}

meta, err := b.fetcher.FetchSourcePackage(reqCtx, pkgAddr.SourceType(), pkgAddr.URL(), workDir)
response, err := b.fetcher.FetchSourcePackage(reqCtx, pkgAddr.SourceType(), pkgAddr.URL(), workDir)
if err != nil {
return "", fmt.Errorf("failed to fetch package: %w", err)
}
if meta != nil {
if response.PackageMeta != nil {
// We'll remember the meta so we can use it when building a manifest later.
b.remotePackageMeta[pkgAddr] = meta
b.remotePackageMeta[pkgAddr] = response.PackageMeta
}

// If the package has a .terraformignore file then we now need to remove
Expand Down
40 changes: 22 additions & 18 deletions sourcebundle/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,8 @@ func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]st
registryPkgs = append(registryPkgs, pkg)
}

fetcher := packageFetcherFunc(func(ctx context.Context, sourceType string, url *url.URL, targetDir string) (*PackageMeta, error) {
fetcher := packageFetcherFunc(func(ctx context.Context, sourceType string, url *url.URL, targetDir string) (FetchSourcePackageResponse, error) {
var ret FetchSourcePackageResponse
// Our fake implementation of "fetching" is to just copy one local
// directory into another.
for _, pkg := range remotePkgs {
Expand All @@ -606,39 +607,42 @@ func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]st
localDir := pkg.localDir
err := copyDir(targetDir, localDir)
if err != nil {
return nil, fmt.Errorf("copying %s to %s: %w", localDir, targetDir, err)
return ret, fmt.Errorf("copying %s to %s: %w", localDir, targetDir, err)
}
return nil, nil
return ret, nil
}
return nil, fmt.Errorf("no fake remote package matches %s %s", sourceType, url)
return ret, fmt.Errorf("no fake remote package matches %s %s", sourceType, url)
})

registryClient := registryClientFuncs{
modulePackageVersions: func(ctx context.Context, pkgAddr regaddr.ModulePackage) (versions.List, error) {
modulePackageVersions: func(ctx context.Context, pkgAddr regaddr.ModulePackage) (ModulePackageVersionsResponse, error) {
var ret ModulePackageVersionsResponse
for _, pkg := range registryPkgs {
if pkg.pkgAddr != pkgAddr {
continue
}
ret := make(versions.List, len(pkg.versions))
ret.Versions = make(versions.List, len(pkg.versions))
for version := range pkg.versions {
ret = append(ret, version)
ret.Versions = append(ret.Versions, version)
}
return ret, nil
}
return nil, fmt.Errorf("no fake registry package matches %s", pkgAddr)
return ret, fmt.Errorf("no fake registry package matches %s", pkgAddr)
},
modulePackageSourceAddr: func(ctx context.Context, pkgAddr regaddr.ModulePackage, version versions.Version) (sourceaddrs.RemoteSource, error) {
modulePackageSourceAddr: func(ctx context.Context, pkgAddr regaddr.ModulePackage, version versions.Version) (ModulePackageSourceAddrResponse, error) {
var ret ModulePackageSourceAddrResponse
for _, pkg := range registryPkgs {
if pkg.pkgAddr != pkgAddr {
continue
}
sourceAddr, ok := pkg.versions[version]
if !ok {
return sourceaddrs.RemoteSource{}, fmt.Errorf("no fake registry package matches %s %s", pkgAddr, version)
return ret, fmt.Errorf("no fake registry package matches %s %s", pkgAddr, version)
}
return sourceAddr, nil
ret.SourceAddr = sourceAddr
return ret, nil
}
return sourceaddrs.RemoteSource{}, fmt.Errorf("no fake registry package matches %s", pkgAddr)
return ret, fmt.Errorf("no fake registry package matches %s", pkgAddr)
},
}

Expand Down Expand Up @@ -719,22 +723,22 @@ func (t *testBuildTracer) appendLogf(f string, v ...interface{}) {
t.log = append(t.log, fmt.Sprintf(f, v...))
}

type packageFetcherFunc func(ctx context.Context, sourceType string, url *url.URL, targetDir string) (*PackageMeta, error)
type packageFetcherFunc func(ctx context.Context, sourceType string, url *url.URL, targetDir string) (FetchSourcePackageResponse, error)

func (f packageFetcherFunc) FetchSourcePackage(ctx context.Context, sourceType string, url *url.URL, targetDir string) (*PackageMeta, error) {
func (f packageFetcherFunc) FetchSourcePackage(ctx context.Context, sourceType string, url *url.URL, targetDir string) (FetchSourcePackageResponse, error) {
return f(ctx, sourceType, url, targetDir)
}

type registryClientFuncs struct {
modulePackageVersions func(ctx context.Context, pkgAddr regaddr.ModulePackage) (versions.List, error)
modulePackageSourceAddr func(ctx context.Context, pkgAddr regaddr.ModulePackage, version versions.Version) (sourceaddrs.RemoteSource, error)
modulePackageVersions func(ctx context.Context, pkgAddr regaddr.ModulePackage) (ModulePackageVersionsResponse, error)
modulePackageSourceAddr func(ctx context.Context, pkgAddr regaddr.ModulePackage, version versions.Version) (ModulePackageSourceAddrResponse, error)
}

func (f registryClientFuncs) ModulePackageVersions(ctx context.Context, pkgAddr regaddr.ModulePackage) (versions.List, error) {
func (f registryClientFuncs) ModulePackageVersions(ctx context.Context, pkgAddr regaddr.ModulePackage) (ModulePackageVersionsResponse, error) {
return f.modulePackageVersions(ctx, pkgAddr)
}

func (f registryClientFuncs) ModulePackageSourceAddr(ctx context.Context, pkgAddr regaddr.ModulePackage, version versions.Version) (sourceaddrs.RemoteSource, error) {
func (f registryClientFuncs) ModulePackageSourceAddr(ctx context.Context, pkgAddr regaddr.ModulePackage, version versions.Version) (ModulePackageSourceAddrResponse, error) {
return f.modulePackageSourceAddr(ctx, pkgAddr, version)
}

Expand Down
10 changes: 8 additions & 2 deletions sourcebundle/package_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

// A PackageFetcher knows how to fetch remote source packages into a local
// filesystem directory.
//
type PackageFetcher interface {
// FetchSourcePackage retrieves the a source package from the given
// location and extracts it into the given local filesystem directory.
Expand All @@ -35,5 +34,12 @@ type PackageFetcher interface {
// because it's [Builder]'s responsibility to handle caching and request
// coalescing during bundle construction to ensure that it will happen
// consistently across different fetcher implementations.
FetchSourcePackage(ctx context.Context, sourceType string, url *url.URL, targetDir string) (*PackageMeta, error)
FetchSourcePackage(ctx context.Context, sourceType string, url *url.URL, targetDir string) (FetchSourcePackageResponse, error)
}

// FetchSourcePackageResponse is a structure which represents metadata about
// the fetch operation. This type may grow to add more data over time in later
// minor releases.
type FetchSourcePackageResponse struct {
PackageMeta *PackageMeta
}
22 changes: 18 additions & 4 deletions sourcebundle/registry_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,25 @@ import (
// information such as the results of performing service discovery against
// the hostname in a module package address.
type RegistryClient interface {
// ModulePackageVersions returns all of the known exact versions
// ModulePackageVersions fetches all of the known exact versions
// available for the given package in its module registry.
ModulePackageVersions(ctx context.Context, pkgAddr regaddr.ModulePackage) (versions.List, error)
ModulePackageVersions(ctx context.Context, pkgAddr regaddr.ModulePackage) (ModulePackageVersionsResponse, error)

// ModulePackageSourceAddr returns the real remote source address for the
// ModulePackageSourceAddr fetches the real remote source address for the
// given version of the given module registry package.
ModulePackageSourceAddr(ctx context.Context, pkgAddr regaddr.ModulePackage, version versions.Version) (sourceaddrs.RemoteSource, error)
ModulePackageSourceAddr(ctx context.Context, pkgAddr regaddr.ModulePackage, version versions.Version) (ModulePackageSourceAddrResponse, error)
}

// ModulePackageVersionsResponse is an opaque type which represents the result
// of the package versions client operation. This type may grow to add more
// functionality over time in later minor releases.
type ModulePackageVersionsResponse struct {
Versions versions.List
}

// ModulePackageSourceAddrResponse is an opaque type which represents the
// result of the source address client operation. This type may grow to add
// more functionality over time in later minor releases.
type ModulePackageSourceAddrResponse struct {
SourceAddr sourceaddrs.RemoteSource
}

0 comments on commit 0ba92f7

Please sign in to comment.