Skip to content

Commit 76a078d

Browse files
committed
envtest: accept entire "ranges" of asset versions
1 parent 5f8f36c commit 76a078d

File tree

1 file changed

+46
-11
lines changed

1 file changed

+46
-11
lines changed

pkg/envtest/binaries.go

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,54 @@ func downloadBinaryAssets(ctx context.Context, binaryAssetsDirectory, binaryAsse
124124
}
125125
}
126126

127+
var requestedRange semver.Range
128+
if binaryAssetsVersion != "" {
129+
binaryAssetsVersion = strings.TrimPrefix(binaryAssetsVersion, "v")
130+
parsedVersion, errV := semver.ParseTolerant(binaryAssetsVersion)
131+
parsedRange, errR := semver.ParseRange(binaryAssetsVersion)
132+
133+
switch {
134+
// When an exact version is requested, don't look for it in the release index.
135+
case errV == nil && parsedVersion.String() == binaryAssetsVersion:
136+
requestedRange = nil
137+
138+
// When the version looks like a range, apply it to the index.
139+
case errR == nil:
140+
requestedRange = parsedRange
141+
142+
// When the version isn't exact, turn it into a range.
143+
//
144+
// The `setup-envtest` tool interprets a partial version to mean "latest stable with that prefix."
145+
// For example, "1" and "1.2" are akin to "1.x.x" and "1.2.x" in [semver.ParseRange].
146+
// [semver.ParseTolerant] fills in missing minor or patch with "0", so this replaces those with "x".
147+
//
148+
// That *should* produce a valid range. If it doesn't, use the original value and skip the index.
149+
case errV == nil:
150+
suffix := strings.TrimPrefix(parsedVersion.FinalizeVersion(), binaryAssetsVersion)
151+
suffix = strings.ReplaceAll(suffix, "0", "x")
152+
parsedRange, errR = semver.ParseRange(binaryAssetsVersion + suffix)
153+
154+
if errR == nil {
155+
requestedRange = parsedRange
156+
} else {
157+
requestedRange = nil
158+
}
159+
}
160+
} else {
161+
// When no version is requested, look for one in the release index.
162+
requestedRange = semver.MustParseRange(">0.0.0")
163+
}
164+
165+
// When a range a versions is requested, select one from the release index.
127166
var binaryAssetsIndex *index
128-
if binaryAssetsVersion == "" || strings.Count(binaryAssetsVersion, ".") < 2 {
167+
if requestedRange != nil {
129168
var err error
130169
binaryAssetsIndex, err = getIndex(ctx, binaryAssetsIndexURL)
131170
if err != nil {
132171
return "", "", "", err
133172
}
134173

135-
binaryAssetsVersion, err = latestStableVersionFromIndex(binaryAssetsIndex, binaryAssetsVersion)
174+
binaryAssetsVersion, err = latestStableVersionFromIndex(binaryAssetsIndex, requestedRange)
136175
if err != nil {
137176
return "", "", "", err
138177
}
@@ -219,6 +258,8 @@ func fileExists(path string) bool {
219258
}
220259

221260
func downloadBinaryAssetsArchive(ctx context.Context, index *index, version string, out io.Writer) error {
261+
version = "v" + strings.TrimPrefix(version, "v")
262+
222263
archives, ok := index.Releases[version]
223264
if !ok {
224265
return fmt.Errorf("failed to find envtest binaries for version %s", version)
@@ -252,26 +293,20 @@ func downloadBinaryAssetsArchive(ctx context.Context, index *index, version stri
252293
return readBody(resp, out, archiveName, archive.Hash)
253294
}
254295

255-
func latestStableVersionFromIndex(index *index, prefix string) (string, error) {
296+
func latestStableVersionFromIndex(index *index, satisfying semver.Range) (string, error) {
256297
if len(index.Releases) == 0 {
257298
return "", fmt.Errorf("failed to find latest stable version from index: index is empty")
258299
}
259300

260-
prefix = strings.TrimPrefix(prefix, "v")
261301
parsedVersions := []semver.Version{}
262302
for releaseVersion := range index.Releases {
263-
// Filter on prefix.
264-
if !strings.HasPrefix(strings.TrimPrefix(releaseVersion, "v"), prefix) {
265-
continue
266-
}
267-
268303
v, err := semver.ParseTolerant(releaseVersion)
269304
if err != nil {
270305
return "", fmt.Errorf("failed to parse version %q: %w", releaseVersion, err)
271306
}
272307

273-
// Filter out pre-releases.
274-
if len(v.Pre) > 0 {
308+
// Filter out pre-releases and undesirable versions.
309+
if len(v.Pre) > 0 || !satisfying(v) {
275310
continue
276311
}
277312

0 commit comments

Comments
 (0)