diff --git a/main/src/main/scala/sbt/internal/CrossJava.scala b/main/src/main/scala/sbt/internal/CrossJava.scala index 4dade4805..845773b7e 100644 --- a/main/src/main/scala/sbt/internal/CrossJava.scala +++ b/main/src/main/scala/sbt/internal/CrossJava.scala @@ -484,17 +484,53 @@ private[sbt] object CrossJava { .toVector } + class SetupJavaDiscoverConfig(base: File) extends JavaDiscoverConf { + private val SetupJavaVendorDir = + """Java_(Zulu|Temurin-Hotspot|Temurin|Adopt|Corretto|Liberica|Microsoft|Semeru)_jdk""".r + private val SetupJavaVersionDir = """([0-9]+)\.([0-9]+)\.([0-9]+)(-[0-9]+)?""".r + + private def normalizeVendor(vendor: String): String = vendor.toLowerCase match { + case "temurin-hotspot" => "temurin" + case "adopt" => "temurin" + case other => other + } + + def candidates(): Vector[String] = wrapNull(base.list()) + + def javaHomes: Vector[(String, File)] = + candidates().flatMap { + case vendorDir @ SetupJavaVendorDir(vendor) => + val vendorPath = base / vendorDir + wrapNull(vendorPath.list()).flatMap { + case versionDir @ SetupJavaVersionDir(major, minor, patch, _) => + val versionPath = vendorPath / versionDir + val archDirs = wrapNull(versionPath.list()) + archDirs.headOption.map { arch => + val javaHome = versionPath / arch + val normalizedVendor = normalizeVendor(vendor) + val version = s"$major.$minor.$patch" + val jv = JavaVersion(version).withVendor(normalizedVendor) + jv.toString -> javaHome + } + case _ => None + } + case _ => Vector.empty + } + } + val configs = Vector( new JabbaDiscoverConfig, new SdkmanDiscoverConfig, new LinuxDiscoverConfig(file("/usr") / "java"), new LinuxDiscoverConfig(file("/usr") / "lib" / "jvm"), + new SetupJavaDiscoverConfig(file("/opt") / "hostedtoolcache"), new MacOsDiscoverConfig, new JavaHomeDiscoverConfig, ) ++ { if (IO.isWindows) { def discover(dir: String, vendors: String*) = new WindowsDiscoverConfig(file(dir), vendors) Vector( + new SetupJavaDiscoverConfig(file("C:") / "hostedtoolcache" / "windows"), discover("C://Program Files/Java", "openjdk"), discover("C://Program Files/Eclipse Foundation", "temurin", "adopt"), discover("C://Program Files/Semeru", "semeru", "adopt-openj9"), diff --git a/main/src/test/scala/sbt/internal/CrossJavaTest.scala b/main/src/test/scala/sbt/internal/CrossJavaTest.scala index 804855a1a..bfd8c8059 100644 --- a/main/src/test/scala/sbt/internal/CrossJavaTest.scala +++ b/main/src/test/scala/sbt/internal/CrossJavaTest.scala @@ -9,9 +9,12 @@ package sbt package internal +import java.io.File import org.scalatest.diagrams.Diagrams import org.scalatest.funsuite.AnyFunSuite import sbt.internal.CrossJava.JavaDiscoverConfig.* +import sbt.io.{ IO, syntax } +import sbt.io.syntax.* import scala.collection.immutable.ListMap class CrossJavaTest extends AnyFunSuite with Diagrams { @@ -193,4 +196,50 @@ class CrossJavaTest extends AnyFunSuite with Diagrams { ) ) } + + test("The setup-java selector should correctly pick up Zulu JDK") { + IO.withTemporaryDirectory { temp => + IO.createDirectory(temp / "Java_Zulu_jdk" / "25.0.1-8" / "x64") + val conf = new SetupJavaDiscoverConfig(temp) + val homes = conf.javaHomes + assert(homes.size == 1) + val (version, javaHome) = homes.head + assert(version == "zulu@25.0.1") + assert(javaHome.getName == "x64") + } + } + + test("The setup-java selector should correctly pick up Temurin JDK") { + IO.withTemporaryDirectory { temp => + IO.createDirectory(temp / "Java_Temurin-Hotspot_jdk" / "11.0.29-7" / "x64") + val conf = new SetupJavaDiscoverConfig(temp) + val homes = conf.javaHomes + assert(homes.size == 1) + val (version, javaHome) = homes.head + assert(version == "temurin@11.0.29") + assert(javaHome.getName == "x64") + } + } + + test("The setup-java selector should normalize Temurin-Hotspot to temurin") { + IO.withTemporaryDirectory { temp => + IO.createDirectory(temp / "Java_Temurin-Hotspot_jdk" / "17.0.5-8" / "x64") + val conf = new SetupJavaDiscoverConfig(temp) + val homes = conf.javaHomes + assert(homes.size == 1) + val (version, _) = homes.head + assert(version == "temurin@17.0.5") + } + } + + test("The setup-java selector should normalize Adopt to temurin") { + IO.withTemporaryDirectory { temp => + IO.createDirectory(temp / "Java_Adopt_jdk" / "11.0.15-10" / "x64") + val conf = new SetupJavaDiscoverConfig(temp) + val homes = conf.javaHomes + assert(homes.size == 1) + val (version, _) = homes.head + assert(version == "temurin@11.0.15") + } + } }