From 7630ed8201969c82a718a6630588fe4b2485f838 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Tue, 3 Jul 2018 11:06:04 +0200 Subject: [PATCH] Select most recent jdk When multiple jdk minor/patch versions are available, select the most recent one. --- .../main/scala/sbt/internal/CrossJava.scala | 52 ++++++++++++++----- .../scala/sbt/internal/CrossJavaTest.scala | 13 +++++ 2 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 main/src/test/scala/sbt/internal/CrossJavaTest.scala diff --git a/main/src/main/scala/sbt/internal/CrossJava.scala b/main/src/main/scala/sbt/internal/CrossJava.scala index 9ee668042..91b829261 100644 --- a/main/src/main/scala/sbt/internal/CrossJava.scala +++ b/main/src/main/scala/sbt/internal/CrossJava.scala @@ -10,6 +10,7 @@ package internal import java.io.File import scala.collection.immutable.ListMap +import scala.annotation.tailrec import sbt.io.Path import sbt.io.syntax._ import sbt.Cross._ @@ -308,24 +309,47 @@ private[sbt] object CrossJava { def javaHomes: Vector[(String, File)] } + // Sort version strings, considering 1.8.0 < 1.8.0_45 < 1.8.0_212 + @tailrec + def versionOrder(left: String, right: String): Boolean = { + val Pattern = """.*?([0-9]+)(.*)""".r + left match { + case Pattern(leftNumber, leftRest) => + right match { + case Pattern(rightNumber, rightRest) => + if (Integer.parseInt(leftNumber) < Integer.parseInt(rightNumber)) true + else if (Integer.parseInt(leftNumber) > Integer.parseInt(rightNumber)) false + else versionOrder(leftRest, rightRest) + case _ => + false + } + case _ => + true + } + } + object JavaDiscoverConfig { val linux = new JavaDiscoverConf { val base: File = file("/usr") / "lib" / "jvm" val JavaHomeDir = """java-([0-9]+)-.*""".r def javaHomes: Vector[(String, File)] = - wrapNull(base.list()).collect { - case dir @ JavaHomeDir(ver) => JavaVersion(ver).toString -> (base / dir) - } + wrapNull(base.list()) + .sortWith(versionOrder) + .collect { + case dir @ JavaHomeDir(ver) => JavaVersion(ver).toString -> (base / dir) + } } val macOS = new JavaDiscoverConf { val base: File = file("/Library") / "Java" / "JavaVirtualMachines" val JavaHomeDir = """jdk-?(1\.)?([0-9]+).*""".r def javaHomes: Vector[(String, File)] = - wrapNull(base.list()).collect { - case dir @ JavaHomeDir(m, n) => - JavaVersion(nullBlank(m) + n).toString -> (base / dir / "Contents" / "Home") - } + wrapNull(base.list()) + .sortWith(versionOrder) + .collect { + case dir @ JavaHomeDir(m, n) => + JavaVersion(nullBlank(m) + n).toString -> (base / dir / "Contents" / "Home") + } } // See https://github.com/shyiko/jabba @@ -333,12 +357,14 @@ private[sbt] object CrossJava { val base: File = Path.userHome / ".jabba" / "jdk" val JavaHomeDir = """([\w\-]+)\@(1\.)?([0-9]+).*""".r def javaHomes: Vector[(String, File)] = - wrapNull(base.list()).collect { - case dir @ JavaHomeDir(vendor, m, n) => - val v = JavaVersion(nullBlank(m) + n).withVendor(vendor).toString - if ((base / dir / "Contents" / "Home").exists) v -> (base / dir / "Contents" / "Home") - else v -> (base / dir) - } + wrapNull(base.list()) + .sortWith(versionOrder) + .collect { + case dir @ JavaHomeDir(vendor, m, n) => + val v = JavaVersion(nullBlank(m) + n).withVendor(vendor).toString + if ((base / dir / "Contents" / "Home").exists) v -> (base / dir / "Contents" / "Home") + else v -> (base / dir) + } } } diff --git a/main/src/test/scala/sbt/internal/CrossJavaTest.scala b/main/src/test/scala/sbt/internal/CrossJavaTest.scala new file mode 100644 index 000000000..8c363391b --- /dev/null +++ b/main/src/test/scala/sbt/internal/CrossJavaTest.scala @@ -0,0 +1,13 @@ +package sbt.internal + +import org.specs2.mutable.Specification + +class CrossJavaTest extends Specification { + "The Java home selector" should { + "select the most recent" in { + List("jdk1.8.0.jdk", "jdk1.8.0_121.jdk", "jdk1.8.0_45.jdk") + .sortWith(CrossJava.versionOrder) + .last must be equalTo ("jdk1.8.0_121.jdk") + } + } +}