From c3cb9c0485b37f5e47360fba301ff50f6b932583 Mon Sep 17 00:00:00 2001 From: AYM1607 Date: Tue, 5 Nov 2024 20:31:29 +0000 Subject: [PATCH] Revert back to the previous implementation. Signed-off-by: AYM1607 --- internal/initwd/module_install.go | 55 ++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/internal/initwd/module_install.go b/internal/initwd/module_install.go index 647c345063..ed32bb78f8 100644 --- a/internal/initwd/module_install.go +++ b/internal/initwd/module_install.go @@ -15,6 +15,7 @@ import ( "path/filepath" "strings" + "github.com/apparentlymart/go-versions/versions" version "github.com/hashicorp/go-version" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" @@ -505,28 +506,44 @@ func (i *ModuleInstaller) installRegistryModule(ctx context.Context, req *config // If we've found a pre-release version then we'll ignore it unless // it was exactly requested. // - // Although the apparentlymart/go-versions library is already used to - // handle constraints for providers, and it natively supports the - // "prerelease versions must be exactly requested". Its previous usage - // in this code path introduced inconsistencies around the handling - // of the "v" prefixes. - // - // If the aforementioned library is to be adopted, it should be - // announced as a breaking change and must be used to handle constraints - // in all scenarios, not just for pre-release versions. + // The prerelease checking will be handled by a different library for + // 2 reasons. First, this other library automatically includes the + // "prerelease versions must be exactly requested" behaviour that we are + // looking for. Second, this other library is used to handle all version + // constraints for the provider logic and this is the first step to + // making the module and provider version logic match. if v.Prerelease() != "" { - conS := req.VersionConstraint.Required.String() - // The exact wording from the docs is: "A prerelease version can be - // selected only by an exact version constraint (the = operator or no operator). - // Prerelease versions do not match inexact operators such as >=, ~>, etc." - // - // Which means that that if the constraint contains any operators - // other than "=", the result from `Check` should be discarded, so - // we can stop at this point. - if strings.ContainsAny(conS, "<>!~^") { - log.Printf("[WARN] ModuleInstaller: %s ignoring %s because the version constraints (%s) contain a non-exact-match operator", key, v, conS) + // At this point all versions published by the module with + // prerelease metadata will be checked. Users may not have even + // requested this prerelease so don't print lots of unnecessary # + // warnings. + acceptableVersions, err := versions.MeetingConstraintsString(req.VersionConstraint.Required.String()) + if err != nil { + log.Printf("[WARN] ModuleInstaller: %s ignoring %s because the version constraints (%s) could not be parsed: %s", key, v, req.VersionConstraint.Required.String(), err.Error()) continue } + + // Validate the version is also readable by the other versions + // library. + version, err := versions.ParseVersion(v.String()) + if err != nil { + log.Printf("[WARN] ModuleInstaller: %s ignoring %s because the version (%s) reported by the module could not be parsed: %s", key, v, v.String(), err.Error()) + continue + } + + // Finally, check if the prerelease is acceptable to version. As + // highlighted previously, we go through all of this because the + // apparentlymart/go-versions library handles prerelease constraints + // in the approach we want to. + if !acceptableVersions.Has(version) { + log.Printf("[TRACE] ModuleInstaller: %s ignoring %s because it is a pre-release and was not requested exactly", key, v) + continue + } + + // If we reach here, it means this prerelease version was exactly + // requested according to the extra constraints of this library. + // We fall through and allow the other library to also validate it + // for consistency. } if latestVersion == nil || v.GreaterThan(latestVersion) {