From b3a6b689713b933f48a2d5862bd026f51c354681 Mon Sep 17 00:00:00 2001 From: Vasil Vasilev Date: Fri, 18 Feb 2022 23:15:01 +0100 Subject: [PATCH 1/9] Add support for the JVM release option for scalac and javac --- .../sbt/TypelevelSettingsPlugin.scala | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index 7d41a241..44496851 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -29,6 +29,9 @@ object TypelevelSettingsPlugin extends AutoPlugin { object autoImport { lazy val tlFatalWarnings = settingKey[Boolean]("Convert compiler warnings into errors (default: false)") + lazy val tlJvmRelease = + settingKey[Int]( + "JVM target version for the compiled bytecode (default: 8, supported values: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)") } import autoImport._ @@ -36,6 +39,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { override def globalSettings = Seq( tlFatalWarnings := false, + tlJvmRelease := 8, Def.derive(scalaVersion := crossScalaVersions.value.last, default = true) ) @@ -201,7 +205,29 @@ object TypelevelSettingsPlugin extends AutoPlugin { Seq("-Werror") else Seq.empty + }, + scalacOptions ++= { + val releaseOption = if (isJava8) Seq() else Seq("-release", tlJvmRelease.value.toString) + val targetOption = if (isJava8) Seq() else Seq(s"-target:${tlJvmRelease.value}") + + scalaVersion.value match { + case V(V(2, 12, Some(build), _)) if build >= 5 => + releaseOption ++ targetOption + + case V(V(2, 13, _, _)) => + releaseOption ++ targetOption + + case V(V(3, _, _, _)) => + releaseOption + + case _ => + Seq.empty + } + }, + javacOptions ++= { + if (isJava8) Seq() else Seq("--release", tlJvmRelease.value.toString) } ) + private val isJava8: Boolean = System.getProperty("java.version").startsWith("1.8") } From efb01f09837df00fdcfe27abcb22d57b51b0c14d Mon Sep 17 00:00:00 2001 From: Vasil Vasilev Date: Fri, 18 Feb 2022 23:37:04 +0100 Subject: [PATCH 2/9] Adjust target option syntax for older compilers --- .../org/typelevel/sbt/TypelevelSettingsPlugin.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index 44496851..e4678843 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -208,14 +208,18 @@ object TypelevelSettingsPlugin extends AutoPlugin { }, scalacOptions ++= { val releaseOption = if (isJava8) Seq() else Seq("-release", tlJvmRelease.value.toString) - val targetOption = if (isJava8) Seq() else Seq(s"-target:${tlJvmRelease.value}") + val newTargetOption = if (isJava8) Seq() else Seq(s"-target:${tlJvmRelease.value}") + val oldTargetOption = if (isJava8) Seq() else Seq(s"-target:jvm-1.8") scalaVersion.value match { + case V(V(2, 11, _, _)) => + oldTargetOption + case V(V(2, 12, Some(build), _)) if build >= 5 => - releaseOption ++ targetOption + releaseOption ++ oldTargetOption case V(V(2, 13, _, _)) => - releaseOption ++ targetOption + releaseOption ++ newTargetOption case V(V(3, _, _, _)) => releaseOption From deb7f68089c33838b46dfb86f98410ca2c0223d9 Mon Sep 17 00:00:00 2001 From: Vasil Vasilev Date: Fri, 18 Feb 2022 23:45:40 +0100 Subject: [PATCH 3/9] Rename jvm to jdk --- .../org/typelevel/sbt/TypelevelSettingsPlugin.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index e4678843..762bd801 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -29,7 +29,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { object autoImport { lazy val tlFatalWarnings = settingKey[Boolean]("Convert compiler warnings into errors (default: false)") - lazy val tlJvmRelease = + lazy val tlJdkRelease = settingKey[Int]( "JVM target version for the compiled bytecode (default: 8, supported values: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)") } @@ -39,7 +39,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { override def globalSettings = Seq( tlFatalWarnings := false, - tlJvmRelease := 8, + tlJdkRelease := 8, Def.derive(scalaVersion := crossScalaVersions.value.last, default = true) ) @@ -207,8 +207,8 @@ object TypelevelSettingsPlugin extends AutoPlugin { Seq.empty }, scalacOptions ++= { - val releaseOption = if (isJava8) Seq() else Seq("-release", tlJvmRelease.value.toString) - val newTargetOption = if (isJava8) Seq() else Seq(s"-target:${tlJvmRelease.value}") + val releaseOption = if (isJava8) Seq() else Seq("-release", tlJdkRelease.value.toString) + val newTargetOption = if (isJava8) Seq() else Seq(s"-target:${tlJdkRelease.value}") val oldTargetOption = if (isJava8) Seq() else Seq(s"-target:jvm-1.8") scalaVersion.value match { @@ -229,7 +229,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { } }, javacOptions ++= { - if (isJava8) Seq() else Seq("--release", tlJvmRelease.value.toString) + if (isJava8) Seq() else Seq("--release", tlJdkRelease.value.toString) } ) From a0816786c02cae91268eff714e0a38e4b6295ba9 Mon Sep 17 00:00:00 2001 From: Vasil Vasilev Date: Mon, 21 Feb 2022 21:31:25 +0100 Subject: [PATCH 4/9] Use an optional value for the key --- .../sbt/TypelevelSettingsPlugin.scala | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index 762bd801..2a85ab22 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -30,8 +30,8 @@ object TypelevelSettingsPlugin extends AutoPlugin { lazy val tlFatalWarnings = settingKey[Boolean]("Convert compiler warnings into errors (default: false)") lazy val tlJdkRelease = - settingKey[Int]( - "JVM target version for the compiled bytecode (default: 8, supported values: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)") + settingKey[Option[Int]]( + "JVM target version for the compiled bytecode, None results in default scalac and javac behavior (no --release flag is specified). (default: Some(8), supported values: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)") } import autoImport._ @@ -39,7 +39,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { override def globalSettings = Seq( tlFatalWarnings := false, - tlJdkRelease := 8, + tlJdkRelease := Some(8), Def.derive(scalaVersion := crossScalaVersions.value.last, default = true) ) @@ -207,9 +207,18 @@ object TypelevelSettingsPlugin extends AutoPlugin { Seq.empty }, scalacOptions ++= { - val releaseOption = if (isJava8) Seq() else Seq("-release", tlJdkRelease.value.toString) - val newTargetOption = if (isJava8) Seq() else Seq(s"-target:${tlJdkRelease.value}") - val oldTargetOption = if (isJava8) Seq() else Seq(s"-target:jvm-1.8") + val releaseOption = tlJdkRelease + .value + .map { release => if (isJava8) Seq() else Seq("-release", release.toString) } + .getOrElse(Seq()) + val newTargetOption = tlJdkRelease + .value + .map { release => if (isJava8) Seq() else Seq(s"-target:$release") } + .getOrElse(Seq()) + val oldTargetOption = tlJdkRelease + .value + .map { _ => if (isJava8) Seq() else Seq(s"-target:jvm-1.8") } + .getOrElse(Seq()) scalaVersion.value match { case V(V(2, 11, _, _)) => From b837ff264d6d134304956fc90a702cf2c9376e96 Mon Sep 17 00:00:00 2001 From: Vasil Vasilev Date: Mon, 21 Feb 2022 21:32:29 +0100 Subject: [PATCH 5/9] Use `Seq.empty` instead of `Seq.apply` --- .../sbt/TypelevelSettingsPlugin.scala | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index 2a85ab22..531a7db1 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -102,7 +102,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { "-Wvalue-discard" ) - val warningsDotty = Seq() + val warningsDotty = Seq.empty scalaVersion.value match { case V(V(3, _, _, _)) => @@ -157,7 +157,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { }, Test / scalacOptions ++= { if (tlIsScala3.value) - Seq() + Seq.empty else Seq("-Yrangepos") }, @@ -209,16 +209,16 @@ object TypelevelSettingsPlugin extends AutoPlugin { scalacOptions ++= { val releaseOption = tlJdkRelease .value - .map { release => if (isJava8) Seq() else Seq("-release", release.toString) } - .getOrElse(Seq()) + .map { release => if (isJava8) Seq.empty else Seq("-release", release.toString) } + .getOrElse(Seq.empty) val newTargetOption = tlJdkRelease .value - .map { release => if (isJava8) Seq() else Seq(s"-target:$release") } - .getOrElse(Seq()) + .map { release => if (isJava8) Seq.empty else Seq(s"-target:$release") } + .getOrElse(Seq.empty) val oldTargetOption = tlJdkRelease .value - .map { _ => if (isJava8) Seq() else Seq(s"-target:jvm-1.8") } - .getOrElse(Seq()) + .map { _ => if (isJava8) Seq.empty else Seq(s"-target:jvm-1.8") } + .getOrElse(Seq.empty) scalaVersion.value match { case V(V(2, 11, _, _)) => @@ -238,7 +238,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { } }, javacOptions ++= { - if (isJava8) Seq() else Seq("--release", tlJdkRelease.value.toString) + if (isJava8) Seq.empty else Seq("--release", tlJdkRelease.value.toString) } ) From e36f991261ae333c61f42a6b5698ba2c4012e89e Mon Sep 17 00:00:00 2001 From: Vasil Vasilev Date: Mon, 21 Feb 2022 21:36:08 +0100 Subject: [PATCH 6/9] Switch the default value to `None` --- .../scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index 531a7db1..8ceecad0 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -31,7 +31,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { settingKey[Boolean]("Convert compiler warnings into errors (default: false)") lazy val tlJdkRelease = settingKey[Option[Int]]( - "JVM target version for the compiled bytecode, None results in default scalac and javac behavior (no --release flag is specified). (default: Some(8), supported values: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)") + "JVM target version for the compiled bytecode, None results in default scalac and javac behavior (no --release flag is specified). (default: None, supported values: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)") } import autoImport._ @@ -39,7 +39,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { override def globalSettings = Seq( tlFatalWarnings := false, - tlJdkRelease := Some(8), + tlJdkRelease := None, Def.derive(scalaVersion := crossScalaVersions.value.last, default = true) ) From e58b9f786c0f6423652361a14d3961d26ce6ea52 Mon Sep 17 00:00:00 2001 From: Vasil Vasilev Date: Mon, 21 Feb 2022 22:40:05 +0100 Subject: [PATCH 7/9] Be more consistent across failure modes --- .../sbt/TypelevelSettingsPlugin.scala | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index 8ceecad0..27011ee1 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -209,15 +209,27 @@ object TypelevelSettingsPlugin extends AutoPlugin { scalacOptions ++= { val releaseOption = tlJdkRelease .value - .map { release => if (isJava8) Seq.empty else Seq("-release", release.toString) } + .map { + case 8 if isJava8 => Seq.empty + case n if n >= 8 => Seq("-release", n.toString) + case n => sys.error(s"'$n' is not a valid choice for '-release'") + } .getOrElse(Seq.empty) val newTargetOption = tlJdkRelease .value - .map { release => if (isJava8) Seq.empty else Seq(s"-target:$release") } + .map { + case 8 if isJava8 => Seq.empty + case n if n >= 8 => Seq(s"-target:$n") + case n => sys.error(s"'$n' is not a valid choice for '-target'") + } .getOrElse(Seq.empty) val oldTargetOption = tlJdkRelease .value - .map { _ => if (isJava8) Seq.empty else Seq(s"-target:jvm-1.8") } + .map { + case 8 if isJava8 => Seq.empty + case n if n >= 8 => Seq(s"-target:jvm-1.8") + case n => sys.error(s"'$n' is not a valid choice for '-target'") + } .getOrElse(Seq.empty) scalaVersion.value match { @@ -238,7 +250,14 @@ object TypelevelSettingsPlugin extends AutoPlugin { } }, javacOptions ++= { - if (isJava8) Seq.empty else Seq("--release", tlJdkRelease.value.toString) + tlJdkRelease + .value + .map { + case 8 if isJava8 => Seq.empty + case n if n >= 8 => Seq("--release", n.toString) + case n => sys.error(s"'$n' is not a valid choice for '--release'") + } + .getOrElse(Seq.empty) } ) From 69daaf4b6d377499007cdf6d2ec12503fa05b028 Mon Sep 17 00:00:00 2001 From: Vasil Vasilev Date: Tue, 22 Feb 2022 12:03:54 +0100 Subject: [PATCH 8/9] Better error messages and DRY --- .../sbt/TypelevelSettingsPlugin.scala | 61 +++++++++---------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index 27011ee1..e9b001d8 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -185,7 +185,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { val infoOpt = scmInfo.value tagOrHash.toSeq flatMap { vh => infoOpt.toSeq flatMap { info => - val path = s"${info.browseUrl}/blob/$vh€{FILE_PATH}.scala" + val path = s"${info.browseUrl}/blob/${vh}€{FILE_PATH}.scala" Seq( "-doc-source-url", path, @@ -207,30 +207,11 @@ object TypelevelSettingsPlugin extends AutoPlugin { Seq.empty }, scalacOptions ++= { - val releaseOption = tlJdkRelease - .value - .map { - case 8 if isJava8 => Seq.empty - case n if n >= 8 => Seq("-release", n.toString) - case n => sys.error(s"'$n' is not a valid choice for '-release'") + val (releaseOption, newTargetOption, oldTargetOption) = + withJdkRelease(tlJdkRelease.value)( + (Seq.empty[String], Seq.empty[String], Seq.empty[String])) { n => + (Seq("-release", n.toString), Seq(s"-target:$n"), Seq("-target:jvm-1.8")) } - .getOrElse(Seq.empty) - val newTargetOption = tlJdkRelease - .value - .map { - case 8 if isJava8 => Seq.empty - case n if n >= 8 => Seq(s"-target:$n") - case n => sys.error(s"'$n' is not a valid choice for '-target'") - } - .getOrElse(Seq.empty) - val oldTargetOption = tlJdkRelease - .value - .map { - case 8 if isJava8 => Seq.empty - case n if n >= 8 => Seq(s"-target:jvm-1.8") - case n => sys.error(s"'$n' is not a valid choice for '-target'") - } - .getOrElse(Seq.empty) scalaVersion.value match { case V(V(2, 11, _, _)) => @@ -250,16 +231,30 @@ object TypelevelSettingsPlugin extends AutoPlugin { } }, javacOptions ++= { - tlJdkRelease - .value - .map { - case 8 if isJava8 => Seq.empty - case n if n >= 8 => Seq("--release", n.toString) - case n => sys.error(s"'$n' is not a valid choice for '--release'") - } - .getOrElse(Seq.empty) + withJdkRelease(tlJdkRelease.value)(Seq.empty[String])(n => Seq("--release", n.toString)) } ) - private val isJava8: Boolean = System.getProperty("java.version").startsWith("1.8") + private def withJdkRelease[A](jdkRelease: Option[Int])(default: => A)(f: Int => A): A = + jdkRelease.fold(default) { + case 8 if isJava8 => default + case n if n >= 8 => + if (javaRuntimeVersion < n) { + sys.error( + s"Target JDK is $n but you are using an older JDK $javaRuntimeVersion. Please switch to JDK >= $n.") + } else { + f(n) + } + case n => + sys.error( + s"You're using JDK $n, which is not supported by `sbt-typelevel`. Please switch to a newer JDK.") + } + + private val javaRuntimeVersion: Int = + System.getProperty("java.version").split("""\.""") match { + case Array("1", "8", _*) => 8 + case Array(feature, _*) => feature.toInt + } + + private val isJava8: Boolean = javaRuntimeVersion == 8 } From 523d4081a15f1ffa56ba54e592ebe8082f50fea2 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Mon, 28 Feb 2022 11:45:06 -0800 Subject: [PATCH 9/9] Correct error message --- .../main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala index e9b001d8..37d08a26 100644 --- a/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala +++ b/settings/src/main/scala/org/typelevel/sbt/TypelevelSettingsPlugin.scala @@ -247,7 +247,7 @@ object TypelevelSettingsPlugin extends AutoPlugin { } case n => sys.error( - s"You're using JDK $n, which is not supported by `sbt-typelevel`. Please switch to a newer JDK.") + s"Target JDK is $n, which is not supported by `sbt-typelevel`. Please select a JDK >= 8.") } private val javaRuntimeVersion: Int =