Skip to content

Commit

Permalink
Add support for new GraalVM Community distributions (#35)
Browse files Browse the repository at this point in the history
* Improve code comments about GraalVM versions
* Add support for new GraalVM Community distributions

In addition to old GraalVM CE distributions, support the new community
distributions that use a new versioning scheme that follows JDK
releases. Resolves #31.

---------

Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
  • Loading branch information
sschuberth committed Jul 6, 2023
1 parent 042aaa1 commit 2d4294f
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ class FoojayApi {
}

internal fun match(distributionName: String, version: JavaLanguageVersion, operatingSystem: OperatingSystem, architecture: Architecture): Package? {
// Old GraalVM releases are special in that the JVM version they target is part of the distribution name instead
// of the release version. For these releases "jdk_version" instead of "version" must be used as they key.
// Old GraalVM releases are special in that the Java language version they target is part of the distribution
// name and the release version is unrelated to the Java language version. That is why for these distributions
// "jdk_version" instead of "version" must be used as the query key.
val versionApiKey = when {
distributionName.startsWith("graalvm_ce") -> "jdk_version"
else -> "version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,39 @@ val j9Aliases = mapOf(
)

/**
* Given a list of [distributions], return those that match the provided [vendor], JVM [implementation], and Java
* language [version].
* Given a list of [distributions], return those that match the provided [vendor] and JVM [implementation]. The Java
* language [version] is only used to remove wrong GraalVM distributions; no general version filtering is done here.
*/
fun match(
distributions: List<Distribution>,
vendor: JvmVendorSpec,
implementation: JvmImplementation,
version: JavaLanguageVersion
): List<Distribution> = when {
JvmImplementation.J9 == implementation -> matchForJ9(distributions, vendor)
JvmVendorSpec.GRAAL_VM == vendor -> match(distributions, JvmVendorSpec.matching("GraalVM CE $version"), version)
else -> match(distributions, vendor, version)
): List<Distribution> {
if (implementation == JvmImplementation.J9) return matchForJ9(distributions, vendor)

// Return early if an explicit non-GraalVM distribution is requested.
if (vendor != JvmVendorSpec.GRAAL_VM && vendor != any()) return match(distributions, vendor)

// Remove GraalVM distributions that target the wrong Java language version.
val graalVmCeVendor = JvmVendorSpec.matching("GraalVM CE $version")
val distributionsWithoutWrongGraalVm = distributions.filter { (name) ->
when {
// Naming scheme for old GraalVM community releases: The Java language version is part of the name.
name.startsWith("GraalVM CE") -> graalVmCeVendor.matches(name)

else -> true
}
}

if (vendor == any()) return allDistributionsPrecededByWellKnownOnes(distributionsWithoutWrongGraalVm)

// As Gradle has no means to distinguish between Community and Oracle distributions of GraalVM (see
// https://github.com/gradle/gradle/issues/25521), disregard Oracle GraalVM distributions for now by only matching
// "GraalVM Community" and "GraalVM CE".
val graalVmVendor = JvmVendorSpec.matching("GraalVM C")

return match(distributionsWithoutWrongGraalVm, graalVmVendor)
}

private fun matchForJ9(distributions: List<Distribution>, vendor: JvmVendorSpec) =
Expand All @@ -53,30 +74,18 @@ private fun matchForJ9(distributions: List<Distribution>, vendor: JvmVendorSpec)
distributions.filter { it.name == j9Aliases[vendor] }
}

private fun match(distributions: List<Distribution>, vendor: JvmVendorSpec, version: JavaLanguageVersion): List<Distribution> {
if (vendor == any()) {
return allDistributionsPrecededByWellKnownOnes(distributions, version)
}
private fun match(distributions: List<Distribution>, vendor: JvmVendorSpec): List<Distribution> =
findByMatchingAliases(distributions, vendor) ?: findByMatchingNamesAndSynonyms(distributions, vendor)

return findByMatchingAliases(distributions, vendor) ?: findByMatchingNamesAndSynonyms(distributions, vendor)
}

private fun allDistributionsPrecededByWellKnownOnes(distributions: List<Distribution>, version: JavaLanguageVersion): List<Distribution> =
distributions
.filter { distribution ->
when {
distribution.name.startsWith("GraalVM CE") -> distribution.name == "GraalVM CE $version"
else -> true
}
}
.sortedBy {
//put our preferences first, preserver Foojay order otherwise
val indexOf = distributionOrderOfPreference.indexOf(it.name)
when {
indexOf < 0 -> distributionOrderOfPreference.size
else -> indexOf
}
private fun allDistributionsPrecededByWellKnownOnes(distributions: List<Distribution>): List<Distribution> =
distributions.sortedBy {
// Put our preferences first, preserve Foojay order otherwise.
val indexOf = distributionOrderOfPreference.indexOf(it.name)
when {
indexOf < 0 -> distributionOrderOfPreference.size
else -> indexOf
}
}

private fun findByMatchingAliases(distributions: List<Distribution>, vendor: JvmVendorSpec): List<Distribution>? =
distributions.find { it.name == vendorAliases[vendor] }?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ class FoojayApiTest {
"https://api.foojay.io/disco/v3.0/ids/74bf5fb0d06e512f88356eb8fe45f67f/redirect",
8, GRAAL_VM, false, OperatingSystem.WINDOWS, Architecture.X86_64
) // graalvm-ce-java8-windows-amd64-21.3.1.zip

assertDownloadUri(
"https://api.foojay.io/disco/v3.0/ids/0254ee795bfd00d22eecc53ec861ea40/redirect",
20, GRAAL_VM, false, OperatingSystem.LINUX, Architecture.X86_64
) // graalvm-community-jdk-20.0.1_linux-x64_bin.tar.gz
}

@ParameterizedTest(name = "J9 implementation influences vendor resolution (Java {0})")
Expand Down Expand Up @@ -119,7 +124,7 @@ class FoojayApiTest {
assertMatchedDistributions(ORACLE, VENDOR_SPECIFIC, version, "Oracle OpenJDK")
assertMatchedDistributions(SAP, VENDOR_SPECIFIC, version, "SAP Machine")

assertMatchedDistributions(GRAAL_VM, VENDOR_SPECIFIC, version, "GraalVM CE $version")
assertMatchedDistributions(GRAAL_VM, VENDOR_SPECIFIC, version, "GraalVM Community", "GraalVM CE $version")

assertMatchedDistributions(APPLE, VENDOR_SPECIFIC, version)
assertMatchedDistributions(HEWLETT_PACKARD, VENDOR_SPECIFIC, version)
Expand Down

0 comments on commit 2d4294f

Please sign in to comment.