From 6d6b2e42cf0e1b2805c097f2ce0d7601120dcf36 Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Tue, 14 May 2024 11:09:43 -0400 Subject: [PATCH 1/8] Expose module deprecation data from the registry within the builder, include it in the manifest --- sourceaddrs/source_remote.go | 11 +++++ sourcebundle/builder.go | 71 +++++++++++++++++++++++++-------- sourcebundle/builder_test.go | 6 ++- sourcebundle/manifest_json.go | 5 ++- sourcebundle/registry_client.go | 12 +++++- 5 files changed, 84 insertions(+), 21 deletions(-) diff --git a/sourceaddrs/source_remote.go b/sourceaddrs/source_remote.go index 87c7c69..1a838ed 100644 --- a/sourceaddrs/source_remote.go +++ b/sourceaddrs/source_remote.go @@ -15,6 +15,17 @@ type RemoteSource struct { subPath string } +type RemoteSourceInfo struct { + RemoteSource RemoteSource + VersionDeprecation *Deprecation +} + +type Deprecation struct { + Version string + Reason string + Link string +} + var _ Source = RemoteSource{} var _ FinalSource = RemoteSource{} diff --git a/sourcebundle/builder.go b/sourcebundle/builder.go index e25d1b1..1829dcc 100644 --- a/sourcebundle/builder.go +++ b/sourcebundle/builder.go @@ -71,14 +71,14 @@ type Builder struct { // resolvedRegistry tracks the underlying remote source address for each // selected version of each module registry package. - resolvedRegistry map[registryPackageVersion]sourceaddrs.RemoteSource + resolvedRegistry map[registryPackageVersion]sourceaddrs.RemoteSourceInfo // registryPackageVersions caches responses from module registry calls to // look up the available versions for a particular module package. Although // these could potentially change while we're running, we assume that the // lifetime of a particular Builder is short enough for that not to // matter. - registryPackageVersions map[regaddr.ModulePackage]versions.List + registryPackageVersions map[regaddr.ModulePackage][]ModulePackageInfo mu sync.Mutex } @@ -106,8 +106,8 @@ func NewBuilder(targetDir string, fetcher PackageFetcher, registryClient Registr analyzed: make(map[remoteArtifact]struct{}), remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), - resolvedRegistry: make(map[registryPackageVersion]sourceaddrs.RemoteSource), - registryPackageVersions: make(map[regaddr.ModulePackage]versions.List), + resolvedRegistry: make(map[registryPackageVersion]sourceaddrs.RemoteSourceInfo), + registryPackageVersions: make(map[regaddr.ModulePackage][]ModulePackageInfo), }, nil } @@ -343,7 +343,8 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour trace := buildTraceFromContext(ctx) pkgAddr := sourceAddr.Package() - availableVersions, ok := b.registryPackageVersions[pkgAddr] + availablePackageInfos, ok := b.registryPackageVersions[pkgAddr] + var availableVersions versions.List if !ok { var reqCtx context.Context if cb := trace.RegistryPackageVersionsStart; cb != nil { @@ -360,14 +361,15 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour } 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 + + availablePackageInfos = resp.Versions + b.registryPackageVersions[pkgAddr] = resp.Versions + availableVersions = extractVersionListFromResponse(availablePackageInfos) if cb := trace.RegistryPackageVersionsSuccess; cb != nil { cb(reqCtx, pkgAddr, availableVersions) } } else { + availableVersions = extractVersionListFromResponse(availablePackageInfos) if cb := trace.RegistryPackageVersionsAlready; cb != nil { cb(ctx, pkgAddr, availableVersions) } @@ -382,7 +384,7 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour pkg: pkgAddr, version: selectedVersion, } - realSourceAddr, ok := b.resolvedRegistry[pkgVer] + realSourceInfo, ok := b.resolvedRegistry[pkgVer] if !ok { var reqCtx context.Context if cb := trace.RegistryPackageSourceStart; cb != nil { @@ -399,14 +401,31 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour } return sourceaddrs.RemoteSource{}, fmt.Errorf("failed to find real source address for %s %s: %w", pkgAddr, selectedVersion, err) } - realSourceAddr = resp.SourceAddr - b.resolvedRegistry[pkgVer] = realSourceAddr + versionDeprecations := extractVersionDeprecationsFromResponse(availablePackageInfos) + versionDeprecation := versionDeprecations[selectedVersion] + if versionDeprecation != nil { + realSourceInfo = sourceaddrs.RemoteSourceInfo{ + RemoteSource: resp.SourceAddr, + VersionDeprecation: &sourceaddrs.Deprecation{ + Version: selectedVersion.String(), + Reason: versionDeprecation.Reason, + Link: versionDeprecation.Link, + }, + } + } else { + realSourceInfo = sourceaddrs.RemoteSourceInfo{ + RemoteSource: resp.SourceAddr, + VersionDeprecation: nil, + } + } + + b.resolvedRegistry[pkgVer] = realSourceInfo if cb := trace.RegistryPackageSourceSuccess; cb != nil { - cb(reqCtx, pkgAddr, selectedVersion, realSourceAddr) + cb(reqCtx, pkgAddr, selectedVersion, realSourceInfo.RemoteSource) } } else { if cb := trace.RegistryPackageSourceAlready; cb != nil { - cb(ctx, pkgAddr, selectedVersion, realSourceAddr) + cb(ctx, pkgAddr, selectedVersion, realSourceInfo.RemoteSource) } } @@ -414,7 +433,7 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour // need to combine that with the one in realSourceAddr to get the correct // final path: the sourceAddr subpath is relative to the realSourceAddr // subpath. - realSourceAddr = sourceAddr.FinalSourceAddr(realSourceAddr) + realSourceAddr := sourceAddr.FinalSourceAddr(realSourceInfo.RemoteSource) return realSourceAddr, nil } @@ -576,7 +595,7 @@ func (b *Builder) writeManifest(filename string) error { }) registryObjs := make(map[regaddr.ModulePackage]*manifestRegistryMeta) - for rpv, sourceAddr := range b.resolvedRegistry { + for rpv, sourceInfo := range b.resolvedRegistry { manifestMeta, ok := registryObjs[rpv.pkg] if !ok { root.RegistryMeta = append(root.RegistryMeta, manifestRegistryMeta{ @@ -587,7 +606,8 @@ func (b *Builder) writeManifest(filename string) error { registryObjs[rpv.pkg] = manifestMeta } manifestMeta.Versions[rpv.version.String()] = manifestRegistryVersion{ - SourceAddr: sourceAddr.String(), + SourceAddr: sourceInfo.RemoteSource.String(), + Deprecation: sourceInfo.VersionDeprecation, } } sort.Slice(root.RegistryMeta, func(i, j int) bool { @@ -713,3 +733,20 @@ func packagePrepareWalkFn(root string, ignoreRules *ignorefiles.Ruleset) filepat return nil } } + +func extractVersionListFromResponse(modPackageInfos []ModulePackageInfo) versions.List { + vs := make(versions.List, len(modPackageInfos)) + for _, v := range modPackageInfos { + vs = append(vs, v.Version) + } + vs.Sort() + return vs +} + +func extractVersionDeprecationsFromResponse(modPackageInfos []ModulePackageInfo) map[versions.Version]*ModulePackageVersionDeprecation { + versionDeprecations := make(map[versions.Version]*ModulePackageVersionDeprecation, len(modPackageInfos)) + for _, v := range modPackageInfos { + versionDeprecations[v.Version] = v.Deprecation + } + return versionDeprecations +} diff --git a/sourcebundle/builder_test.go b/sourcebundle/builder_test.go index 61cfffc..6404e4d 100644 --- a/sourcebundle/builder_test.go +++ b/sourcebundle/builder_test.go @@ -621,9 +621,11 @@ func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]st if pkg.pkgAddr != pkgAddr { continue } - ret.Versions = make(versions.List, len(pkg.versions)) + ret.Versions = make([]ModulePackageVersion, len(pkg.versions)) for version := range pkg.versions { - ret.Versions = append(ret.Versions, version) + ret.Versions = append(ret.Versions, ModulePackageVersion{ + Version: version, + }) } return ret, nil } diff --git a/sourcebundle/manifest_json.go b/sourcebundle/manifest_json.go index b371e6d..ee9324f 100644 --- a/sourcebundle/manifest_json.go +++ b/sourcebundle/manifest_json.go @@ -3,6 +3,8 @@ package sourcebundle +import "github.com/hashicorp/go-slug/sourceaddrs" + // This file contains some internal-only types used to help with marshalling // and unmarshalling our manifest file format. The manifest format is not // itself a public interface, so these should stay unexported and any caller @@ -43,7 +45,8 @@ type manifestRegistryVersion struct { // This SourceAddr is a full source address, so it might potentially // have a sub-path portion. If it does then it must be combined with // any sub-path included in the user's registry module source address. - SourceAddr string `json:"source"` + SourceAddr string `json:"source"` + Deprecation *sourceaddrs.Deprecation `json:"deprecation"` } type manifestPackageMeta struct { diff --git a/sourcebundle/registry_client.go b/sourcebundle/registry_client.go index fa3fc57..6135a59 100644 --- a/sourcebundle/registry_client.go +++ b/sourcebundle/registry_client.go @@ -34,7 +34,17 @@ type RegistryClient interface { // 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 + Versions []ModulePackageInfo `json:"versions"` +} + +type ModulePackageInfo struct { + Version versions.Version + Deprecation *ModulePackageVersionDeprecation `json:"deprecation"` +} + +type ModulePackageVersionDeprecation struct { + Reason string `json:"reason"` + Link string `json:"link"` } // ModulePackageSourceAddrResponse is an opaque type which represents the From bb038d6e06d6f5e779f97ddfb781e0b87562569a Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Tue, 4 Jun 2024 19:19:36 -0400 Subject: [PATCH 2/8] Include module version deprecation data in bundle --- sourcebundle/bundle.go | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/sourcebundle/bundle.go b/sourcebundle/bundle.go index 8f28cd4..7b00e02 100644 --- a/sourcebundle/bundle.go +++ b/sourcebundle/bundle.go @@ -32,7 +32,7 @@ type Bundle struct { remotePackageDirs map[sourceaddrs.RemotePackage]string remotePackageMeta map[sourceaddrs.RemotePackage]*PackageMeta - registryPackageSources map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSource + registryPackageSources map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSourceInfo } // OpenDir opens a bundle rooted at the given base directory. @@ -54,7 +54,7 @@ func OpenDir(baseDir string) (*Bundle, error) { rootDir: rootDir, remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), - registryPackageSources: make(map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSource), + registryPackageSources: make(map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSourceInfo), } manifestSrc, err := os.ReadFile(filepath.Join(rootDir, manifestFilename)) @@ -105,7 +105,7 @@ func OpenDir(baseDir string) (*Bundle, error) { } vs := ret.registryPackageSources[pkgAddr] if vs == nil { - vs = make(map[versions.Version]sourceaddrs.RemoteSource) + vs = make(map[versions.Version]sourceaddrs.RemoteSourceInfo) ret.registryPackageSources[pkgAddr] = vs } for versionStr, mv := range rpm.Versions { @@ -117,7 +117,10 @@ func OpenDir(baseDir string) (*Bundle, error) { if err != nil { return nil, fmt.Errorf("invalid registry package source address %q: %w", mv.SourceAddr, err) } - vs[version] = sourceAddr + vs[version] = sourceaddrs.RemoteSourceInfo{ + RemoteSource: sourceAddr, + VersionDeprecation: mv.Deprecation, + } } } @@ -171,14 +174,14 @@ func (b *Bundle) LocalPathForRegistrySource(addr sourceaddrs.RegistrySource, ver if !ok { return "", fmt.Errorf("source bundle does not include %s", pkgAddr) } - baseSourceAddr, ok := vs[version] + baseSourceInfo, ok := vs[version] if !ok { return "", fmt.Errorf("source bundle does not include %s v%s", pkgAddr, version) } // The address we were given might have its own source address, so we need // to incorporate that into our result. - finalSourceAddr := addr.FinalSourceAddr(baseSourceAddr) + finalSourceAddr := addr.FinalSourceAddr(baseSourceInfo.RemoteSource) return b.LocalPathForRemoteSource(finalSourceAddr) } @@ -354,12 +357,17 @@ func (b *Bundle) RegistryPackageVersions(pkgAddr regaddr.ModulePackage) versions return ret } +func (b *Bundle) RegistryPackageSourceInfo(pkgAddr regaddr.ModulePackage, version versions.Version) (sourceaddrs.RemoteSourceInfo, bool) { + sourceInfo, ok := b.registryPackageSources[pkgAddr][version] + return sourceInfo, ok +} + // RegistryPackageSourceAddr returns the remote source address corresponding // to the given version of the given module package, or sets its second return // value to false if no such version is included in the bundle. func (b *Bundle) RegistryPackageSourceAddr(pkgAddr regaddr.ModulePackage, version versions.Version) (sourceaddrs.RemoteSource, bool) { sourceAddr, ok := b.registryPackageSources[pkgAddr][version] - return sourceAddr, ok + return sourceAddr.RemoteSource, ok } // WriteArchive writes a source bundle archive containing the same contents From ef8c8ac12b705d88097b57429ac5b1fe921fdc08 Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Tue, 4 Jun 2024 19:19:52 -0400 Subject: [PATCH 3/8] test fix --- sourcebundle/builder_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sourcebundle/builder_test.go b/sourcebundle/builder_test.go index 6404e4d..c8f3533 100644 --- a/sourcebundle/builder_test.go +++ b/sourcebundle/builder_test.go @@ -621,9 +621,9 @@ func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]st if pkg.pkgAddr != pkgAddr { continue } - ret.Versions = make([]ModulePackageVersion, len(pkg.versions)) + ret.Versions = make([]ModulePackageInfo, len(pkg.versions)) for version := range pkg.versions { - ret.Versions = append(ret.Versions, ModulePackageVersion{ + ret.Versions = append(ret.Versions, ModulePackageInfo{ Version: version, }) } From 3fa65750f5638397e8c92aa9bc469e4d7d628c52 Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Thu, 6 Jun 2024 12:09:15 -0400 Subject: [PATCH 4/8] feedback from @brandonc: move deprecation related types to sourcebundle, use index to append elements to slice with known length and capacity --- sourceaddrs/source_registry.go | 6 ++++ sourceaddrs/source_remote.go | 11 ------ sourcebundle/builder.go | 61 +++++++++++++++++----------------- sourcebundle/bundle.go | 37 ++++++++++++--------- sourcebundle/manifest_json.go | 4 +-- 5 files changed, 60 insertions(+), 59 deletions(-) diff --git a/sourceaddrs/source_registry.go b/sourceaddrs/source_registry.go index 20509fc..976d371 100644 --- a/sourceaddrs/source_registry.go +++ b/sourceaddrs/source_registry.go @@ -29,6 +29,12 @@ type RegistrySource struct { subPath string } +type RegistryVersionDeprecation struct { + Version string + Reason string + Link string +} + // sourceSigil implements Source func (s RegistrySource) sourceSigil() {} diff --git a/sourceaddrs/source_remote.go b/sourceaddrs/source_remote.go index 1a838ed..87c7c69 100644 --- a/sourceaddrs/source_remote.go +++ b/sourceaddrs/source_remote.go @@ -15,17 +15,6 @@ type RemoteSource struct { subPath string } -type RemoteSourceInfo struct { - RemoteSource RemoteSource - VersionDeprecation *Deprecation -} - -type Deprecation struct { - Version string - Reason string - Link string -} - var _ Source = RemoteSource{} var _ FinalSource = RemoteSource{} diff --git a/sourcebundle/builder.go b/sourcebundle/builder.go index 1829dcc..1fce624 100644 --- a/sourcebundle/builder.go +++ b/sourcebundle/builder.go @@ -71,7 +71,9 @@ type Builder struct { // resolvedRegistry tracks the underlying remote source address for each // selected version of each module registry package. - resolvedRegistry map[registryPackageVersion]sourceaddrs.RemoteSourceInfo + resolvedRegistry map[registryPackageVersion]sourceaddrs.RemoteSource + + resolvedRegistryVersionDeprecations map[registryPackageVersion]*sourceaddrs.RegistryVersionDeprecation // registryPackageVersions caches responses from module registry calls to // look up the available versions for a particular module package. Although @@ -100,14 +102,15 @@ func NewBuilder(targetDir string, fetcher PackageFetcher, registryClient Registr return nil, fmt.Errorf("invalid target directory: %w", err) } return &Builder{ - targetDir: absDir, - fetcher: fetcher, - registryClient: registryClient, - analyzed: make(map[remoteArtifact]struct{}), - remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), - remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), - resolvedRegistry: make(map[registryPackageVersion]sourceaddrs.RemoteSourceInfo), - registryPackageVersions: make(map[regaddr.ModulePackage][]ModulePackageInfo), + targetDir: absDir, + fetcher: fetcher, + registryClient: registryClient, + analyzed: make(map[remoteArtifact]struct{}), + remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), + remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), + resolvedRegistry: make(map[registryPackageVersion]sourceaddrs.RemoteSource), + resolvedRegistryVersionDeprecations: make(map[registryPackageVersion]*sourceaddrs.RegistryVersionDeprecation), + registryPackageVersions: make(map[regaddr.ModulePackage][]ModulePackageInfo), }, nil } @@ -384,7 +387,7 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour pkg: pkgAddr, version: selectedVersion, } - realSourceInfo, ok := b.resolvedRegistry[pkgVer] + realSourceAddr, ok := b.resolvedRegistry[pkgVer] if !ok { var reqCtx context.Context if cb := trace.RegistryPackageSourceStart; cb != nil { @@ -401,31 +404,27 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour } return sourceaddrs.RemoteSource{}, fmt.Errorf("failed to find real source address for %s %s: %w", pkgAddr, selectedVersion, err) } + realSourceAddr = resp.SourceAddr + b.resolvedRegistry[pkgVer] = realSourceAddr + + var deprecation *sourceaddrs.RegistryVersionDeprecation versionDeprecations := extractVersionDeprecationsFromResponse(availablePackageInfos) versionDeprecation := versionDeprecations[selectedVersion] if versionDeprecation != nil { - realSourceInfo = sourceaddrs.RemoteSourceInfo{ - RemoteSource: resp.SourceAddr, - VersionDeprecation: &sourceaddrs.Deprecation{ - Version: selectedVersion.String(), - Reason: versionDeprecation.Reason, - Link: versionDeprecation.Link, - }, - } - } else { - realSourceInfo = sourceaddrs.RemoteSourceInfo{ - RemoteSource: resp.SourceAddr, - VersionDeprecation: nil, + deprecation = &sourceaddrs.RegistryVersionDeprecation{ + Version: selectedVersion.String(), + Reason: versionDeprecation.Reason, + Link: versionDeprecation.Link, } } + b.resolvedRegistryVersionDeprecations[pkgVer] = deprecation - b.resolvedRegistry[pkgVer] = realSourceInfo if cb := trace.RegistryPackageSourceSuccess; cb != nil { - cb(reqCtx, pkgAddr, selectedVersion, realSourceInfo.RemoteSource) + cb(reqCtx, pkgAddr, selectedVersion, realSourceAddr) } } else { if cb := trace.RegistryPackageSourceAlready; cb != nil { - cb(ctx, pkgAddr, selectedVersion, realSourceInfo.RemoteSource) + cb(ctx, pkgAddr, selectedVersion, realSourceAddr) } } @@ -433,7 +432,7 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour // need to combine that with the one in realSourceAddr to get the correct // final path: the sourceAddr subpath is relative to the realSourceAddr // subpath. - realSourceAddr := sourceAddr.FinalSourceAddr(realSourceInfo.RemoteSource) + realSourceAddr = sourceAddr.FinalSourceAddr(realSourceAddr) return realSourceAddr, nil } @@ -605,11 +604,13 @@ func (b *Builder) writeManifest(filename string) error { manifestMeta = &root.RegistryMeta[len(root.RegistryMeta)-1] registryObjs[rpv.pkg] = manifestMeta } + deprecation := b.resolvedRegistryVersionDeprecations[rpv] manifestMeta.Versions[rpv.version.String()] = manifestRegistryVersion{ - SourceAddr: sourceInfo.RemoteSource.String(), - Deprecation: sourceInfo.VersionDeprecation, + SourceAddr: sourceInfo.String(), + Deprecation: deprecation, } } + sort.Slice(root.RegistryMeta, func(i, j int) bool { return root.Packages[i].SourceAddr < root.Packages[j].SourceAddr }) @@ -736,8 +737,8 @@ func packagePrepareWalkFn(root string, ignoreRules *ignorefiles.Ruleset) filepat func extractVersionListFromResponse(modPackageInfos []ModulePackageInfo) versions.List { vs := make(versions.List, len(modPackageInfos)) - for _, v := range modPackageInfos { - vs = append(vs, v.Version) + for index, v := range modPackageInfos { + vs[index] = v.Version } vs.Sort() return vs diff --git a/sourcebundle/bundle.go b/sourcebundle/bundle.go index 7b00e02..8324088 100644 --- a/sourcebundle/bundle.go +++ b/sourcebundle/bundle.go @@ -32,7 +32,8 @@ type Bundle struct { remotePackageDirs map[sourceaddrs.RemotePackage]string remotePackageMeta map[sourceaddrs.RemotePackage]*PackageMeta - registryPackageSources map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSourceInfo + registryPackageSources map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSource + registryPackageVersionDeprecations map[regaddr.ModulePackage]map[versions.Version]*sourceaddrs.RegistryVersionDeprecation } // OpenDir opens a bundle rooted at the given base directory. @@ -51,10 +52,11 @@ func OpenDir(baseDir string) (*Bundle, error) { } ret := &Bundle{ - rootDir: rootDir, - remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), - remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), - registryPackageSources: make(map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSourceInfo), + rootDir: rootDir, + remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), + remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), + registryPackageSources: make(map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSource), + registryPackageVersionDeprecations: make(map[regaddr.ModulePackage]map[versions.Version]*sourceaddrs.RegistryVersionDeprecation), } manifestSrc, err := os.ReadFile(filepath.Join(rootDir, manifestFilename)) @@ -105,22 +107,25 @@ func OpenDir(baseDir string) (*Bundle, error) { } vs := ret.registryPackageSources[pkgAddr] if vs == nil { - vs = make(map[versions.Version]sourceaddrs.RemoteSourceInfo) + vs = make(map[versions.Version]sourceaddrs.RemoteSource) ret.registryPackageSources[pkgAddr] = vs } + deprecations := ret.registryPackageVersionDeprecations[pkgAddr] + if deprecations == nil { + deprecations = make(map[versions.Version]*sourceaddrs.RegistryVersionDeprecation) + ret.registryPackageVersionDeprecations[pkgAddr] = deprecations + } for versionStr, mv := range rpm.Versions { version, err := versions.ParseVersion(versionStr) if err != nil { return nil, fmt.Errorf("invalid registry package version %q: %w", versionStr, err) } + deprecations[version] = mv.Deprecation sourceAddr, err := sourceaddrs.ParseRemoteSource(mv.SourceAddr) if err != nil { return nil, fmt.Errorf("invalid registry package source address %q: %w", mv.SourceAddr, err) } - vs[version] = sourceaddrs.RemoteSourceInfo{ - RemoteSource: sourceAddr, - VersionDeprecation: mv.Deprecation, - } + vs[version] = sourceAddr } } @@ -174,14 +179,14 @@ func (b *Bundle) LocalPathForRegistrySource(addr sourceaddrs.RegistrySource, ver if !ok { return "", fmt.Errorf("source bundle does not include %s", pkgAddr) } - baseSourceInfo, ok := vs[version] + baseSourceAddr, ok := vs[version] if !ok { return "", fmt.Errorf("source bundle does not include %s v%s", pkgAddr, version) } // The address we were given might have its own source address, so we need // to incorporate that into our result. - finalSourceAddr := addr.FinalSourceAddr(baseSourceInfo.RemoteSource) + finalSourceAddr := addr.FinalSourceAddr(baseSourceAddr) return b.LocalPathForRemoteSource(finalSourceAddr) } @@ -357,9 +362,9 @@ func (b *Bundle) RegistryPackageVersions(pkgAddr regaddr.ModulePackage) versions return ret } -func (b *Bundle) RegistryPackageSourceInfo(pkgAddr regaddr.ModulePackage, version versions.Version) (sourceaddrs.RemoteSourceInfo, bool) { - sourceInfo, ok := b.registryPackageSources[pkgAddr][version] - return sourceInfo, ok +func (b *Bundle) RegistryPackageVersionDeprecation(pkgAddr regaddr.ModulePackage, version versions.Version) *sourceaddrs.RegistryVersionDeprecation { + deprecation := b.registryPackageVersionDeprecations[pkgAddr][version] + return deprecation } // RegistryPackageSourceAddr returns the remote source address corresponding @@ -367,7 +372,7 @@ func (b *Bundle) RegistryPackageSourceInfo(pkgAddr regaddr.ModulePackage, versio // value to false if no such version is included in the bundle. func (b *Bundle) RegistryPackageSourceAddr(pkgAddr regaddr.ModulePackage, version versions.Version) (sourceaddrs.RemoteSource, bool) { sourceAddr, ok := b.registryPackageSources[pkgAddr][version] - return sourceAddr.RemoteSource, ok + return sourceAddr, ok } // WriteArchive writes a source bundle archive containing the same contents diff --git a/sourcebundle/manifest_json.go b/sourcebundle/manifest_json.go index ee9324f..e65d057 100644 --- a/sourcebundle/manifest_json.go +++ b/sourcebundle/manifest_json.go @@ -45,8 +45,8 @@ type manifestRegistryVersion struct { // This SourceAddr is a full source address, so it might potentially // have a sub-path portion. If it does then it must be combined with // any sub-path included in the user's registry module source address. - SourceAddr string `json:"source"` - Deprecation *sourceaddrs.Deprecation `json:"deprecation"` + SourceAddr string `json:"source"` + Deprecation *sourceaddrs.RegistryVersionDeprecation `json:"deprecation"` } type manifestPackageMeta struct { From e1d3105998c4859c8a49b7e490e02366d581aeba Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Thu, 6 Jun 2024 13:43:47 -0400 Subject: [PATCH 5/8] added test --- sourcebundle/builder_test.go | 115 ++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/sourcebundle/builder_test.go b/sourcebundle/builder_test.go index c8f3533..e812f9c 100644 --- a/sourcebundle/builder_test.go +++ b/sourcebundle/builder_test.go @@ -44,6 +44,7 @@ func TestBuilderSimple(t *testing.T) { "1.0.0": "https://example.com/foo.tgz", }, }, + nil, ) realSource := sourceaddrs.MustParseSource("https://example.com/foo.tgz").(sourceaddrs.RemoteSource) @@ -114,6 +115,7 @@ func TestBuilderSubdirs(t *testing.T) { "1.0.0": "https://example.com/subdirs.tgz//a", }, }, + nil, ) // NOTE: We're asking for subdir "b" of the registry address. That combines @@ -183,6 +185,7 @@ func TestBuilderRemoteDeps(t *testing.T) { "https://example.com/dependency2.tgz": "testdata/pkgs/terraformignore", }, nil, + nil, ) startSource := sourceaddrs.MustParseSource("https://example.com/with-deps.tgz").(sourceaddrs.RemoteSource) @@ -269,6 +272,92 @@ func TestBuilderRemoteDeps(t *testing.T) { }) } +func TestBuilderRegistryVersionDeprecation(t *testing.T) { + // This tests the common pattern of specifying a module registry address + // to start, having that translated into a real remote source address, + // and then downloading from that real source address. There are no + // oddities or edge-cases here. + + tracer := testBuildTracer{} + ctx := tracer.OnContext(context.Background()) + + targetDir := t.TempDir() + builder := testingBuilder( + t, targetDir, + map[string]string{ + "https://example.com/foo.tgz": "testdata/pkgs/hello", + }, + map[string]map[string]string{ + "example.com/foo/bar/baz": { + "1.0.0": "https://example.com/foo.tgz", + }, + }, + map[string]map[string]*ModulePackageVersionDeprecation{ + "example.com/foo/bar/baz": { + "1.0.0": &ModulePackageVersionDeprecation{ + Reason: "test reason", + Link: "test link", + }, + }, + }, + ) + + realSource := sourceaddrs.MustParseSource("https://example.com/foo.tgz").(sourceaddrs.RemoteSource) + regSource := sourceaddrs.MustParseSource("example.com/foo/bar/baz").(sourceaddrs.RegistrySource) + diags := builder.AddRegistrySource(ctx, regSource, versions.All, noDependencyFinder) + if len(diags) > 0 { + t.Fatal("unexpected diagnostics") + } + + bundle, err := builder.Close() + + if err != nil { + t.Fatalf("failed to close bundle: %s", err) + } + + version, _ := versions.ParseVersion("1.0.0") + pkgAddr, _ := sourceaddrs.ParseRegistryPackage("example.com/foo/bar/baz") + + wantDeprecations := map[regaddr.ModulePackage]map[versions.Version]*sourceaddrs.RegistryVersionDeprecation{ + pkgAddr: { + version: &sourceaddrs.RegistryVersionDeprecation{ + Version: "1.0.0", + Reason: "test reason", + Link: "test link", + }, + }, + } + gotDeprecations := bundle.registryPackageVersionDeprecations + if diff := cmp.Diff(wantDeprecations, gotDeprecations); diff != "" { + t.Errorf("wrong deprecations\n%s", diff) + } + + localPkgDir, err := bundle.LocalPathForRemoteSource(realSource) + if err != nil { + for pkgAddr, localDir := range builder.remotePackageDirs { + t.Logf("contents of %s are in %s", pkgAddr, localDir) + } + t.Fatalf("builder does not know a local directory for %s: %s", realSource.Package(), err) + } + + if info, err := os.Lstat(filepath.Join(localPkgDir, "hello")); err != nil { + t.Errorf("problem with output file: %s", err) + } else if !info.Mode().IsRegular() { + t.Errorf("output file is not a regular file") + } + + // Looking up the original registry address at the selected version + // should return the same directory, because the registry address is just + // an indirection over the same source address. + registryPkgDir, err := bundle.LocalPathForRegistrySource(regSource, versions.MustParseVersion("1.0.0")) + if err != nil { + t.Fatalf("builder does not know a local directory for %s: %s", regSource.Package(), err) + } + if registryPkgDir != localPkgDir { + t.Errorf("local dir for %s doesn't match local dir for %s", regSource, realSource) + } +} + func TestBuilderRemoteDepsDifferingTypes(t *testing.T) { tracer := testBuildTracer{} ctx := tracer.OnContext(context.Background()) @@ -282,6 +371,7 @@ func TestBuilderRemoteDepsDifferingTypes(t *testing.T) { "https://example.com/dependency2.tgz": "testdata/pkgs/terraformignore", }, nil, + nil, ) startSource := sourceaddrs.MustParseSource("https://example.com/self_dependency.tgz").(sourceaddrs.RemoteSource) @@ -383,6 +473,7 @@ func TestBuilderTerraformIgnore(t *testing.T) { "https://example.com/ignore.tgz": "testdata/pkgs/terraformignore", }, nil, + nil, ) startSource := sourceaddrs.MustParseSource("https://example.com/ignore.tgz").(sourceaddrs.RemoteSource) @@ -442,6 +533,7 @@ func TestBuilderCoalescePackages(t *testing.T) { "https://example.com/dependency2.tgz": "testdata/pkgs/hello", }, nil, + nil, ) startSource := sourceaddrs.MustParseSource("https://example.com/with-deps.tgz").(sourceaddrs.RemoteSource) @@ -542,7 +634,7 @@ func TestBuilderCoalescePackages(t *testing.T) { }) } -func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]string, registryPackages map[string]map[string]string) *Builder { +func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]string, registryPackages map[string]map[string]string, registryVersionDeprecations map[string]map[string]*ModulePackageVersionDeprecation) *Builder { t.Helper() type fakeRemotePackage struct { @@ -557,6 +649,7 @@ func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]st remotePkgs := make([]fakeRemotePackage, 0, len(remotePackages)) registryPkgs := make([]fakeRegistryPackage, 0, len(registryPackages)) + registryDeprecations := make(map[string]map[versions.Version]*ModulePackageVersionDeprecation) for pkgAddrRaw, localDir := range remotePackages { pkgAddr, err := sourceaddrs.ParseRemotePackage(pkgAddrRaw) @@ -593,6 +686,23 @@ func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]st registryPkgs = append(registryPkgs, pkg) } + for pkgAddrRaw, deprecations := range registryVersionDeprecations { + pkgAddr, err := sourceaddrs.ParseRegistryPackage(pkgAddrRaw) + if err != nil { + t.Fatalf("invalid registry package address %q: %s", pkgAddrRaw, err) + } + if registryDeprecations[pkgAddr.Namespace] == nil { + registryDeprecations[pkgAddr.Namespace] = make(map[versions.Version]*ModulePackageVersionDeprecation) + } + for versionRaw, versionDeprecation := range deprecations { + version, err := versions.ParseVersion(versionRaw) + if err != nil { + t.Fatalf("invalid registry package version %q for %s: %s", versionRaw, pkgAddr, err) + } + registryDeprecations[pkgAddr.Namespace][version] = versionDeprecation + } + } + 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 @@ -624,7 +734,8 @@ func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]st ret.Versions = make([]ModulePackageInfo, len(pkg.versions)) for version := range pkg.versions { ret.Versions = append(ret.Versions, ModulePackageInfo{ - Version: version, + Version: version, + Deprecation: registryDeprecations[pkg.pkgAddr.Namespace][version], }) } return ret, nil From 3914531de8f47b7389c6ef0afc28e9dd38c33a09 Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Thu, 6 Jun 2024 15:36:51 -0400 Subject: [PATCH 6/8] move RegistryVersionDeprecation to sourcebundle package --- sourceaddrs/source_registry.go | 6 ------ sourcebundle/builder.go | 8 ++++---- sourcebundle/builder_test.go | 4 ++-- sourcebundle/bundle.go | 8 ++++---- sourcebundle/manifest_json.go | 6 ++---- sourcebundle/package_meta.go | 6 ++++++ 6 files changed, 18 insertions(+), 20 deletions(-) diff --git a/sourceaddrs/source_registry.go b/sourceaddrs/source_registry.go index 976d371..20509fc 100644 --- a/sourceaddrs/source_registry.go +++ b/sourceaddrs/source_registry.go @@ -29,12 +29,6 @@ type RegistrySource struct { subPath string } -type RegistryVersionDeprecation struct { - Version string - Reason string - Link string -} - // sourceSigil implements Source func (s RegistrySource) sourceSigil() {} diff --git a/sourcebundle/builder.go b/sourcebundle/builder.go index 1fce624..e2c421d 100644 --- a/sourcebundle/builder.go +++ b/sourcebundle/builder.go @@ -73,7 +73,7 @@ type Builder struct { // selected version of each module registry package. resolvedRegistry map[registryPackageVersion]sourceaddrs.RemoteSource - resolvedRegistryVersionDeprecations map[registryPackageVersion]*sourceaddrs.RegistryVersionDeprecation + resolvedRegistryVersionDeprecations map[registryPackageVersion]*RegistryVersionDeprecation // registryPackageVersions caches responses from module registry calls to // look up the available versions for a particular module package. Although @@ -109,7 +109,7 @@ func NewBuilder(targetDir string, fetcher PackageFetcher, registryClient Registr remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), resolvedRegistry: make(map[registryPackageVersion]sourceaddrs.RemoteSource), - resolvedRegistryVersionDeprecations: make(map[registryPackageVersion]*sourceaddrs.RegistryVersionDeprecation), + resolvedRegistryVersionDeprecations: make(map[registryPackageVersion]*RegistryVersionDeprecation), registryPackageVersions: make(map[regaddr.ModulePackage][]ModulePackageInfo), }, nil } @@ -407,11 +407,11 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour realSourceAddr = resp.SourceAddr b.resolvedRegistry[pkgVer] = realSourceAddr - var deprecation *sourceaddrs.RegistryVersionDeprecation + var deprecation *RegistryVersionDeprecation versionDeprecations := extractVersionDeprecationsFromResponse(availablePackageInfos) versionDeprecation := versionDeprecations[selectedVersion] if versionDeprecation != nil { - deprecation = &sourceaddrs.RegistryVersionDeprecation{ + deprecation = &RegistryVersionDeprecation{ Version: selectedVersion.String(), Reason: versionDeprecation.Reason, Link: versionDeprecation.Link, diff --git a/sourcebundle/builder_test.go b/sourcebundle/builder_test.go index e812f9c..5149a9b 100644 --- a/sourcebundle/builder_test.go +++ b/sourcebundle/builder_test.go @@ -318,9 +318,9 @@ func TestBuilderRegistryVersionDeprecation(t *testing.T) { version, _ := versions.ParseVersion("1.0.0") pkgAddr, _ := sourceaddrs.ParseRegistryPackage("example.com/foo/bar/baz") - wantDeprecations := map[regaddr.ModulePackage]map[versions.Version]*sourceaddrs.RegistryVersionDeprecation{ + wantDeprecations := map[regaddr.ModulePackage]map[versions.Version]*RegistryVersionDeprecation{ pkgAddr: { - version: &sourceaddrs.RegistryVersionDeprecation{ + version: &RegistryVersionDeprecation{ Version: "1.0.0", Reason: "test reason", Link: "test link", diff --git a/sourcebundle/bundle.go b/sourcebundle/bundle.go index 8324088..8ff08fd 100644 --- a/sourcebundle/bundle.go +++ b/sourcebundle/bundle.go @@ -33,7 +33,7 @@ type Bundle struct { remotePackageMeta map[sourceaddrs.RemotePackage]*PackageMeta registryPackageSources map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSource - registryPackageVersionDeprecations map[regaddr.ModulePackage]map[versions.Version]*sourceaddrs.RegistryVersionDeprecation + registryPackageVersionDeprecations map[regaddr.ModulePackage]map[versions.Version]*RegistryVersionDeprecation } // OpenDir opens a bundle rooted at the given base directory. @@ -56,7 +56,7 @@ func OpenDir(baseDir string) (*Bundle, error) { remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), registryPackageSources: make(map[regaddr.ModulePackage]map[versions.Version]sourceaddrs.RemoteSource), - registryPackageVersionDeprecations: make(map[regaddr.ModulePackage]map[versions.Version]*sourceaddrs.RegistryVersionDeprecation), + registryPackageVersionDeprecations: make(map[regaddr.ModulePackage]map[versions.Version]*RegistryVersionDeprecation), } manifestSrc, err := os.ReadFile(filepath.Join(rootDir, manifestFilename)) @@ -112,7 +112,7 @@ func OpenDir(baseDir string) (*Bundle, error) { } deprecations := ret.registryPackageVersionDeprecations[pkgAddr] if deprecations == nil { - deprecations = make(map[versions.Version]*sourceaddrs.RegistryVersionDeprecation) + deprecations = make(map[versions.Version]*RegistryVersionDeprecation) ret.registryPackageVersionDeprecations[pkgAddr] = deprecations } for versionStr, mv := range rpm.Versions { @@ -362,7 +362,7 @@ func (b *Bundle) RegistryPackageVersions(pkgAddr regaddr.ModulePackage) versions return ret } -func (b *Bundle) RegistryPackageVersionDeprecation(pkgAddr regaddr.ModulePackage, version versions.Version) *sourceaddrs.RegistryVersionDeprecation { +func (b *Bundle) RegistryPackageVersionDeprecation(pkgAddr regaddr.ModulePackage, version versions.Version) *RegistryVersionDeprecation { deprecation := b.registryPackageVersionDeprecations[pkgAddr][version] return deprecation } diff --git a/sourcebundle/manifest_json.go b/sourcebundle/manifest_json.go index e65d057..a97b395 100644 --- a/sourcebundle/manifest_json.go +++ b/sourcebundle/manifest_json.go @@ -3,8 +3,6 @@ package sourcebundle -import "github.com/hashicorp/go-slug/sourceaddrs" - // This file contains some internal-only types used to help with marshalling // and unmarshalling our manifest file format. The manifest format is not // itself a public interface, so these should stay unexported and any caller @@ -45,8 +43,8 @@ type manifestRegistryVersion struct { // This SourceAddr is a full source address, so it might potentially // have a sub-path portion. If it does then it must be combined with // any sub-path included in the user's registry module source address. - SourceAddr string `json:"source"` - Deprecation *sourceaddrs.RegistryVersionDeprecation `json:"deprecation"` + SourceAddr string `json:"source"` + Deprecation *RegistryVersionDeprecation `json:"deprecation"` } type manifestPackageMeta struct { diff --git a/sourcebundle/package_meta.go b/sourcebundle/package_meta.go index 993c302..a184db9 100644 --- a/sourcebundle/package_meta.go +++ b/sourcebundle/package_meta.go @@ -20,6 +20,12 @@ type PackageMeta struct { gitCommitMessage string } +type RegistryVersionDeprecation struct { + Version string + Reason string + Link string +} + // PackageMetaWithGitMetadata returns a [PackageMeta] object with a Git Commit // ID and message tracked. // From ea8f696aaf4615b5eed02231bed0038ff283c397 Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Fri, 7 Jun 2024 14:24:39 -0400 Subject: [PATCH 7/8] Updated with feedback from @brandonc: comments, improve variable names, remove unneed map reallocation --- sourcebundle/builder.go | 26 ++++++++++++++------------ sourcebundle/builder_test.go | 8 ++++---- sourcebundle/bundle.go | 3 +-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/sourcebundle/builder.go b/sourcebundle/builder.go index e2c421d..96b0897 100644 --- a/sourcebundle/builder.go +++ b/sourcebundle/builder.go @@ -73,7 +73,9 @@ type Builder struct { // selected version of each module registry package. resolvedRegistry map[registryPackageVersion]sourceaddrs.RemoteSource - resolvedRegistryVersionDeprecations map[registryPackageVersion]*RegistryVersionDeprecation + // resolvedRegistryVersionDeprecations tracks potential deprecations for + // each package version + packageVersionDeprecations map[registryPackageVersion]*RegistryVersionDeprecation // registryPackageVersions caches responses from module registry calls to // look up the available versions for a particular module package. Although @@ -102,15 +104,15 @@ func NewBuilder(targetDir string, fetcher PackageFetcher, registryClient Registr return nil, fmt.Errorf("invalid target directory: %w", err) } return &Builder{ - targetDir: absDir, - fetcher: fetcher, - registryClient: registryClient, - analyzed: make(map[remoteArtifact]struct{}), - remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), - remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), - resolvedRegistry: make(map[registryPackageVersion]sourceaddrs.RemoteSource), - resolvedRegistryVersionDeprecations: make(map[registryPackageVersion]*RegistryVersionDeprecation), - registryPackageVersions: make(map[regaddr.ModulePackage][]ModulePackageInfo), + targetDir: absDir, + fetcher: fetcher, + registryClient: registryClient, + analyzed: make(map[remoteArtifact]struct{}), + remotePackageDirs: make(map[sourceaddrs.RemotePackage]string), + remotePackageMeta: make(map[sourceaddrs.RemotePackage]*PackageMeta), + resolvedRegistry: make(map[registryPackageVersion]sourceaddrs.RemoteSource), + packageVersionDeprecations: make(map[registryPackageVersion]*RegistryVersionDeprecation), + registryPackageVersions: make(map[regaddr.ModulePackage][]ModulePackageInfo), }, nil } @@ -417,7 +419,7 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour Link: versionDeprecation.Link, } } - b.resolvedRegistryVersionDeprecations[pkgVer] = deprecation + b.packageVersionDeprecations[pkgVer] = deprecation if cb := trace.RegistryPackageSourceSuccess; cb != nil { cb(reqCtx, pkgAddr, selectedVersion, realSourceAddr) @@ -604,7 +606,7 @@ func (b *Builder) writeManifest(filename string) error { manifestMeta = &root.RegistryMeta[len(root.RegistryMeta)-1] registryObjs[rpv.pkg] = manifestMeta } - deprecation := b.resolvedRegistryVersionDeprecations[rpv] + deprecation := b.packageVersionDeprecations[rpv] manifestMeta.Versions[rpv.version.String()] = manifestRegistryVersion{ SourceAddr: sourceInfo.String(), Deprecation: deprecation, diff --git a/sourcebundle/builder_test.go b/sourcebundle/builder_test.go index 5149a9b..33257f2 100644 --- a/sourcebundle/builder_test.go +++ b/sourcebundle/builder_test.go @@ -691,15 +691,15 @@ func testingBuilder(t *testing.T, targetDir string, remotePackages map[string]st if err != nil { t.Fatalf("invalid registry package address %q: %s", pkgAddrRaw, err) } - if registryDeprecations[pkgAddr.Namespace] == nil { - registryDeprecations[pkgAddr.Namespace] = make(map[versions.Version]*ModulePackageVersionDeprecation) - } + for versionRaw, versionDeprecation := range deprecations { version, err := versions.ParseVersion(versionRaw) if err != nil { t.Fatalf("invalid registry package version %q for %s: %s", versionRaw, pkgAddr, err) } - registryDeprecations[pkgAddr.Namespace][version] = versionDeprecation + registryDeprecations[pkgAddr.Namespace] = map[versions.Version]*ModulePackageVersionDeprecation{ + version: versionDeprecation, + } } } diff --git a/sourcebundle/bundle.go b/sourcebundle/bundle.go index 8ff08fd..0c0b7ef 100644 --- a/sourcebundle/bundle.go +++ b/sourcebundle/bundle.go @@ -363,8 +363,7 @@ func (b *Bundle) RegistryPackageVersions(pkgAddr regaddr.ModulePackage) versions } func (b *Bundle) RegistryPackageVersionDeprecation(pkgAddr regaddr.ModulePackage, version versions.Version) *RegistryVersionDeprecation { - deprecation := b.registryPackageVersionDeprecations[pkgAddr][version] - return deprecation + return b.registryPackageVersionDeprecations[pkgAddr][version] } // RegistryPackageSourceAddr returns the remote source address corresponding From be5d90781af6a49d0b5f5dc5fca24e185629c14a Mon Sep 17 00:00:00 2001 From: Mark DeCrane Date: Mon, 10 Jun 2024 15:07:05 -0400 Subject: [PATCH 8/8] Updated with feedback from @alisdair --- sourcebundle/builder.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sourcebundle/builder.go b/sourcebundle/builder.go index 96b0897..9419cc8 100644 --- a/sourcebundle/builder.go +++ b/sourcebundle/builder.go @@ -73,8 +73,10 @@ type Builder struct { // selected version of each module registry package. resolvedRegistry map[registryPackageVersion]sourceaddrs.RemoteSource - // resolvedRegistryVersionDeprecations tracks potential deprecations for - // each package version + // packageVersionDeprecations tracks potential deprecations for + // each package version. If a package version is not deprecated, its mapped value will be nil. + // This data, including both package versions and their potential deprecations, is gathered from the registry client and cached. It is included in the bundle, + // where it can be used to warn about deprecated package versions. packageVersionDeprecations map[registryPackageVersion]*RegistryVersionDeprecation // registryPackageVersions caches responses from module registry calls to @@ -409,9 +411,15 @@ func (b *Builder) findRegistryPackageSource(ctx context.Context, sourceAddr sour realSourceAddr = resp.SourceAddr b.resolvedRegistry[pkgVer] = realSourceAddr + var versionDeprecation *ModulePackageVersionDeprecation + for _, v := range availablePackageInfos { + if selectedVersion.Same(v.Version) { + versionDeprecation = v.Deprecation + break + } + + } var deprecation *RegistryVersionDeprecation - versionDeprecations := extractVersionDeprecationsFromResponse(availablePackageInfos) - versionDeprecation := versionDeprecations[selectedVersion] if versionDeprecation != nil { deprecation = &RegistryVersionDeprecation{ Version: selectedVersion.String(), @@ -745,11 +753,3 @@ func extractVersionListFromResponse(modPackageInfos []ModulePackageInfo) version vs.Sort() return vs } - -func extractVersionDeprecationsFromResponse(modPackageInfos []ModulePackageInfo) map[versions.Version]*ModulePackageVersionDeprecation { - versionDeprecations := make(map[versions.Version]*ModulePackageVersionDeprecation, len(modPackageInfos)) - for _, v := range modPackageInfos { - versionDeprecations[v.Version] = v.Deprecation - } - return versionDeprecations -}