detection of SDKMAN managed JDKs

This commit is contained in:
Eugene Yokota 2019-03-26 00:32:46 -04:00
parent 6f19f76b40
commit c0cd65af92
4 changed files with 132 additions and 11 deletions

View File

@ -6,26 +6,32 @@
package sbt
final class JavaVersion private (
val numbers: Vector[Long],
val tags: Vector[String],
val vendor: Option[String]) extends Serializable {
def numberStr: String = numbers.mkString(".")
private def tagStr: String = if (tags.isEmpty) "" else tags.mkString("-", "-", "")
private def this() = this(Vector(), Vector(), None)
private def this(numbers: Vector[Long], vendor: Option[String]) = this(numbers, Vector(), vendor)
override def equals(o: Any): Boolean = o match {
case x: JavaVersion => (this.numbers == x.numbers) && (this.vendor == x.vendor)
case x: JavaVersion => (this.numbers == x.numbers) && (this.tags == x.tags) && (this.vendor == x.vendor)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (17 + "sbt.JavaVersion".##) + numbers.##) + vendor.##)
37 * (37 * (37 * (37 * (17 + "sbt.JavaVersion".##) + numbers.##) + tags.##) + vendor.##)
}
override def toString: String = {
vendor.map(_ + "@").getOrElse("") + numberStr
vendor.map(_ + "@").getOrElse("") + numberStr + tagStr
}
private[this] def copy(numbers: Vector[Long] = numbers, vendor: Option[String] = vendor): JavaVersion = {
new JavaVersion(numbers, vendor)
private[this] def copy(numbers: Vector[Long] = numbers, tags: Vector[String] = tags, vendor: Option[String] = vendor): JavaVersion = {
new JavaVersion(numbers, tags, vendor)
}
def withNumbers(numbers: Vector[Long]): JavaVersion = {
copy(numbers = numbers)
}
def withTags(tags: Vector[String]): JavaVersion = {
copy(tags = tags)
}
def withVendor(vendor: Option[String]): JavaVersion = {
copy(vendor = vendor)
}
@ -35,6 +41,9 @@ final class JavaVersion private (
}
object JavaVersion {
def apply(version: String): JavaVersion = sbt.internal.CrossJava.parseJavaVersion(version)
def apply(): JavaVersion = new JavaVersion()
def apply(numbers: Vector[Long], vendor: Option[String]): JavaVersion = new JavaVersion(numbers, vendor)
def apply(numbers: Vector[Long], vendor: String): JavaVersion = new JavaVersion(numbers, Option(vendor))
def apply(numbers: Vector[Long], tags: Vector[String], vendor: Option[String]): JavaVersion = new JavaVersion(numbers, tags, vendor)
def apply(numbers: Vector[Long], tags: Vector[String], vendor: String): JavaVersion = new JavaVersion(numbers, tags, Option(vendor))
}

View File

@ -19,11 +19,13 @@ enum PluginTrigger {
}
type JavaVersion {
numbers: [Long]
vendor: String
numbers: [Long] @since("1.2.0")
tags: [String] @since("1.3.0")
vendor: String @since("1.2.0")
#x def numberStr: String = numbers.mkString(".")
#xtostring vendor.map(_ + "@").getOrElse("") + numberStr
#x private def tagStr: String = if (tags.isEmpty) "" else tags.mkString("-", "-", "")
#xtostring vendor.map(_ + "@").getOrElse("") + numberStr + tagStr
#xcompanion def apply(version: String): JavaVersion = sbt.internal.CrossJava.parseJavaVersion(version)
}

View File

@ -45,6 +45,49 @@ private[sbt] object CrossJava {
}
}
def parseSdkmanString(version: String): JavaVersion = {
val Num = """([0-9]+)""".r
def splitDash(str: String): Vector[String] =
Option(str) match {
case Some(x) => x.split('-').toVector
case _ => Vector()
}
def splitDot(str: String): Vector[String] =
Option(str) match {
case Some(x) => x.split('.').toVector.filterNot(_ == "")
case _ => Vector()
}
splitDash(version) match {
case xs if xs.size < 2 => sys.error(s"Invalid SDKMAN Java version: $version")
case xs =>
val ds = splitDot(xs.init.head)
val nums = ds.takeWhile(
_ match {
case Num(_) => true
case _ => false
}
) map { _.toLong }
val nonNum = ds.drop(nums.size).mkString("")
// last dash indicates vendor code
val (vnd0, tag0) = (xs.last, nonNum) match {
case ("adpt", "hs") => ("adpt", "")
case ("adpt", "j9") => ("adopt-openj9", "")
case (v, t) => (v, t)
}
val vnd = vnd0 match {
case "adpt" => "adopt"
case "open" => "openjdk"
case "grl" => "graalvm"
case "amzn" => "corretto"
case _ => vnd0
}
val tag1: String = xs.init.tail.mkString("")
val tags = (if (tag0 == "") Vector.empty[String] else Vector(tag0)) ++
(if (tag1 == "") Vector.empty[String] else Vector(tag1))
JavaVersion().withNumbers(nums).withVendor(vnd).withTags(tags)
}
}
def lookupJavaHome(jv: String, mappings: Map[String, File]): File = {
val ms = mappings map { case (k, v) => (JavaVersion(k), v) }
lookupJavaHome(JavaVersion(jv), ms)
@ -377,6 +420,18 @@ private[sbt] object CrossJava {
}
}
class SdkmanDiscoverConfig extends JavaDiscoverConf {
val base: File = Path.userHome / ".sdkman" / "candidates" / "java"
def candidates(): Vector[String] = wrapNull(base.list())
def javaHomes: Vector[(String, File)] =
candidates
.collect {
case dir if dir.contains("-") =>
val v = CrossJava.parseSdkmanString(dir).toString
v -> (base / dir)
}
}
class WindowsDiscoverConfig(base: File) extends JavaDiscoverConf {
def candidates() = wrapNull(base.list())
@ -408,6 +463,7 @@ private[sbt] object CrossJava {
val configs = Vector(
new JabbaDiscoverConfig,
new SdkmanDiscoverConfig,
new LinuxDiscoverConfig(file("/usr") / "java"),
new LinuxDiscoverConfig(file("/usr") / "lib" / "jvm"),
new MacOsDiscoverConfig,

View File

@ -5,7 +5,8 @@
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.internal
package sbt
package internal
import org.scalatest._
import sbt.internal.CrossJava.JavaDiscoverConfig._
@ -66,7 +67,7 @@ class CrossJavaTest extends FunSuite with DiagrammedAssertions {
assert(file.getName == "jdk8")
}
test("The JAVA_HOME selector correctly pick up an Oracle JDK") {
test("The JAVA_HOME selector should correctly pick up an Oracle JDK") {
val conf = new JavaHomeDiscoverConfig {
override def home() = Some("/opt/oracle-jdk-bin-1.8.0.181")
}
@ -74,4 +75,57 @@ class CrossJavaTest extends FunSuite with DiagrammedAssertions {
assert(version == "1.8")
assert(file.getName == "oracle-jdk-bin-1.8.0.181")
}
test("The SDKMAN selector should correctly pick up an AdoptOpenJDK") {
val conf = new SdkmanDiscoverConfig {
override def candidates() = Vector("11.0.2.hs-adpt")
}
val (version, file) = conf.javaHomes.sortWith(CrossJava.versionOrder).last
assert(version == "adopt@11.0.2")
assert(file.getName == "11.0.2.hs-adpt")
}
test("SDKMAN candidate parsing") {
assert(
CrossJava
.parseSdkmanString("11.0.2.hs-adpt") == JavaVersion(Vector(11L, 0L, 2L), Some("adopt"))
)
assert(
CrossJava
.parseSdkmanString("11.0.2.j9-adpt") == JavaVersion(
Vector(11L, 0L, 2L),
Some("adopt-openj9")
)
)
assert(
CrossJava
.parseSdkmanString("13.ea.13-open") == JavaVersion(
Vector(13L),
Vector("ea13"),
Some("openjdk")
)
)
assert(
CrossJava
.parseSdkmanString("12.0.0-zulu") == JavaVersion(
Vector(12L, 0L, 0L),
Some("zulu")
)
)
assert(
CrossJava
.parseSdkmanString("8.0.201-oracle") == JavaVersion(
Vector(8L, 0L, 201L),
Some("oracle")
)
)
assert(
CrossJava
.parseSdkmanString("1.0.0-rc-14-grl") == JavaVersion(
Vector(1L, 0L, 0L),
Vector("rc14"),
Some("graalvm")
)
)
}
}