From 41c2c97aa9b52b8771ef08a963ee8c95abb2607e Mon Sep 17 00:00:00 2001 From: Chongyi Zheng Date: Sat, 30 Mar 2024 03:59:45 -0400 Subject: [PATCH] Support arm64 minor variants Signed-off-by: Chongyi Zheng Signed-off-by: Samuel Karp --- compare.go | 62 ++++++++++++++++++++++ compare_test.go | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ database.go | 7 ++- platforms.go | 2 +- 4 files changed, 203 insertions(+), 2 deletions(-) diff --git a/compare.go b/compare.go index 3913ef6..0abe541 100644 --- a/compare.go +++ b/compare.go @@ -72,6 +72,66 @@ func platformVector(platform specs.Platform) []specs.Platform { if variant == "" { variant = "v8" } + + majorVariant, minorVariant, hasMinor := strings.Cut(variant, ".") + if armMajor, err := strconv.Atoi(strings.TrimPrefix(majorVariant, "v")); err == nil && armMajor >= 8 { + armMinor := 0 + if len(variant) == 4 { + if minor, err := strconv.Atoi(minorVariant); err == nil && hasMinor { + armMinor = minor + } + } + + if armMajor == 9 { + for minor := armMinor - 1; minor >= 0; minor-- { + arm64Variant := "v" + strconv.Itoa(armMajor) + "." + strconv.Itoa(minor) + if minor == 0 { + arm64Variant = "v" + strconv.Itoa(armMajor) + } + vector = append(vector, specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: arm64Variant, + }) + } + + // v9.0 diverged from v8.5, meaning that v9.x is compatible with v8.{x+5} until v9.4/v8.9 + armMinor = armMinor + 5 + if armMinor > 9 { + armMinor = 9 + } + armMajor = 8 + vector = append(vector, specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: "v8." + strconv.Itoa(armMinor), + }) + } + + for minor := armMinor - 1; minor >= 0; minor-- { + arm64Variant := "v" + strconv.Itoa(armMajor) + "." + strconv.Itoa(minor) + if minor == 0 { + arm64Variant = "v" + strconv.Itoa(armMajor) + } + vector = append(vector, specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: arm64Variant, + }) + } + } + + // All arm64/v8.x and arm64/v9.x are compatible with arm/v8 (32-bits) and below. + // There's no arm64 v9 variant, so it's normalized to v8. + if strings.HasPrefix(variant, "v8.") || strings.HasPrefix(variant, "v9.") { + variant = "v8" + } vector = append(vector, platformVector(specs.Platform{ Architecture: "arm", OS: platform.OS, @@ -87,6 +147,8 @@ func platformVector(platform specs.Platform) []specs.Platform { // Only returns a match comparer for a single platform // using default resolution logic for the platform. // +// For arm64/v9.x, will also match arm64/v9.{0..x-1} and arm64/v8.{0..x+5} +// For arm64/v8.x, will also match arm64/v8.{0..x-1} // For arm/v8, will also match arm/v7, arm/v6 and arm/v5 // For arm/v7, will also match arm/v6 and arm/v5 // For arm/v6, will also match arm/v5 diff --git a/compare_test.go b/compare_test.go index 2c276d0..c514bf0 100644 --- a/compare_test.go +++ b/compare_test.go @@ -185,6 +185,95 @@ func TestOnly(t *testing.T) { }, }, }, + { + platform: "linux/arm64/v9.6", + matches: map[bool][]string{ + true: { + "linux/arm", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7", + "linux/arm/v8", + "linux/arm64", + "linux/arm64/v8", + "linux/arm64/v8.1", + "linux/arm64/v8.2", + "linux/arm64/v8.3", + "linux/arm64/v8.4", + "linux/arm64/v8.5", + "linux/arm64/v8.6", + "linux/arm64/v8.7", + "linux/arm64/v8.8", + "linux/arm64/v8.9", + "linux/arm64/v9", + "linux/arm64/v9.0", + "linux/arm64/v9.1", + "linux/arm64/v9.2", + "linux/arm64/v9.3", + "linux/arm64/v9.4", + "linux/arm64/v9.5", + "linux/arm64/v9.6", + }, + false: { + "linux/amd64", + "linux/arm/v4", + "windows/amd64", + "windows/arm", + "linux/arm64/v8.10", // there's no v8.10 + }, + }, + }, + { + platform: "linux/arm64/v9", + matches: map[bool][]string{ + true: { + "linux/arm", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7", + "linux/arm/v8", + "linux/arm64", + "linux/arm64/v8", + "linux/arm64/v8.1", + "linux/arm64/v8.2", + "linux/arm64/v8.3", + "linux/arm64/v8.4", + "linux/arm64/v8.5", + "linux/arm64/v9", + "linux/arm64/v9.0", + }, + false: { + "linux/amd64", + "linux/arm/v4", + "windows/amd64", + "windows/arm", + "linux/arm64/v8.6", + }, + }, + }, + { + platform: "linux/arm64/v8.1", + matches: map[bool][]string{ + true: { + "linux/arm", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7", + "linux/arm/v8", + "linux/arm64", + "linux/arm64/v8", + "linux/arm64/v8.1", + }, + false: { + "linux/amd64", + "linux/arm/v4", + "linux/arm/v9", + "linux/arm64/v9", + "windows/amd64", + "windows/arm", + }, + }, + }, { platform: "linux/arm64", matches: map[bool][]string{ @@ -390,6 +479,51 @@ func TestOnlyStrict(t *testing.T) { }, }, }, + { + platform: "linux/arm64/v9", + matches: map[bool][]string{ + true: { + "linux/arm64/v9", + "linux/arm64/v9.0", + }, + false: { + "linux/arm", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7", + "linux/arm/v8", + "linux/amd64", + "linux/arm/v4", + "linux/arm/v9", + "linux/arm64/v8", + "linux/arm64/v8.1", + "windows/amd64", + "windows/arm", + }, + }, + }, + { + platform: "linux/arm64/v8.1", + matches: map[bool][]string{ + true: { + "linux/arm64/v8.1", + }, + false: { + "linux/arm", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7", + "linux/arm/v8", + "linux/amd64", + "linux/arm/v4", + "linux/arm/v9", + "linux/arm64/v8", + "linux/arm64/v9", + "windows/amd64", + "windows/arm", + }, + }, + }, { platform: "linux/arm64", matches: map[bool][]string{ diff --git a/database.go b/database.go index 2e26fd3..113bbab 100644 --- a/database.go +++ b/database.go @@ -87,8 +87,13 @@ func normalizeArch(arch, variant string) (string, string) { case "aarch64", "arm64": arch = "arm64" switch variant { - case "8", "v8": + case "8", "v8", "8.0", "v8.0": variant = "" + case "9", "9.0", "v9.0": + variant = "v9" + case "8.1", "8.2", "8.3", "8.4", "8.5", "8.6", "8.7", "8.8", "8.9", + "9.1", "9.2", "9.3", "9.4", "9.5": + variant = "v" + variant } case "armhf": arch = "arm" diff --git a/platforms.go b/platforms.go index 1bbbdb9..7a84449 100644 --- a/platforms.go +++ b/platforms.go @@ -121,7 +121,7 @@ import ( ) var ( - specifierRe = regexp.MustCompile(`^[A-Za-z0-9_-]+$`) + specifierRe = regexp.MustCompile(`^[A-Za-z0-9_.-]+$`) osAndVersionRe = regexp.MustCompile(`^([A-Za-z0-9_-]+)(?:\(([A-Za-z0-9_.-]*)\))?$`) )