diff --git a/build.mill.scala b/build.mill.scala index 63e4287c8f..dc5325e605 100644 --- a/build.mill.scala +++ b/build.mill.scala @@ -524,6 +524,12 @@ trait Core extends ScalaCliCrossSbtModule | def scala3NextPrefix = "${Scala.scala3NextPrefix}" | def scala3LtsPrefix = "${Scala.scala3LtsPrefix}" | def scala3Lts = "${Scala.scala3Lts}" + | + | def scala38Versions = Seq(${Scala.scala38Versions + .sorted + .map(s => s"\"$s\"") + .mkString(", ")}) + | def scala38MinJavaVersion = ${Java.minimumScala38Java} | | def workspaceDirName = "$workspaceDirName" | def projectFileName = "$projectFileName" @@ -1032,6 +1038,7 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests .sorted .map(s => s"\"$s\"") .mkString(", ")}) + | def scala38MinJavaVersion = ${Java.minimumScala38Java} | def defaultScalafmtVersion = "${Deps.scalafmtCli.dep.versionConstraint.asString}" | def maxAmmoniteScala212Version = "${Scala.maxAmmoniteScala212Version}" | def maxAmmoniteScala213Version = "${Scala.maxAmmoniteScala213Version}" diff --git a/modules/core/src/main/scala/scala/build/CsUtils.scala b/modules/core/src/main/scala/scala/build/CsUtils.scala index 396b391aa2..0c3c8cad65 100644 --- a/modules/core/src/main/scala/scala/build/CsUtils.scala +++ b/modules/core/src/main/scala/scala/build/CsUtils.scala @@ -2,4 +2,12 @@ package scala.build import coursier.version.Version +import scala.build.internal.Constants + extension (s: String) def coursierVersion: Version = Version(s) + +extension (csv: Version) + def isScala38OrNewer: Boolean = + Constants.scala38Versions + .map(_.coursierVersion) + .exists(_ <= csv) diff --git a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala index 99b9644884..b2ce606bf5 100755 --- a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala @@ -2430,23 +2430,32 @@ abstract class RunTestDefinitions } } - test( - s"run a simple hello world with the runner module on the classpath and Scala $actualScalaVersion" - ) { - val expectedMessage = "Hello, world!" - val legacyRunnerWarning = "Defaulting to a legacy runner module version" - TestInputs(os.rel / "script.sc" -> s"""println("$expectedMessage")""") - .fromRoot { root => - val res = os.proc(TestUtil.cli, "run", ".", "--runner", extraOptions) - .call(cwd = root, stderr = os.Pipe) - expect(res.out.trim() == expectedMessage) - val legacyWarningCheck = { - val check = res.err.trim().contains(legacyRunnerWarning) - if (actualScalaVersion.startsWith("2")) check else !check - } - expect(legacyWarningCheck) - } + for { + javaVersion <- + if isScala38OrNewer then + Constants.allJavaVersions.filter(_ >= Constants.scala38MinJavaVersion) + else Constants.allJavaVersions.filter(_ < 24) } + test( + s"run a simple hello world with the runner module on the classpath, Scala $actualScalaVersion and Java $javaVersion" + ) { + val expectedMessage = "Hello, world!" + val legacyRunnerWarning = "Defaulting to a legacy runner module version" + TestInputs(os.rel / "script.sc" -> s"""println("$expectedMessage")""") + .fromRoot { root => + val res = + os.proc(TestUtil.cli, "run", ".", "--runner", extraOptions, "--jvm", javaVersion) + .call(cwd = root, stderr = os.Pipe) + expect(res.out.trim() == expectedMessage) + val legacyWarningCheck = { + val check = res.err.trim().contains(legacyRunnerWarning) + val shouldCheck = + javaVersion < Constants.scala38MinJavaVersion || actualScalaVersion.startsWith("2") + if shouldCheck then check else !check + } + expect(legacyWarningCheck) + } + } for (parallelInstancesCount <- Seq(2, 5, 10)) test( diff --git a/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala index 8fd3711518..76e9bcba99 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala @@ -4,6 +4,7 @@ import com.eed3si9n.expecty.Expecty.expect import scala.annotation.tailrec import scala.cli.integration.Constants.munitVersion +import scala.cli.integration.TestUtil.StringOps abstract class TestTestDefinitions extends ScalaCliSuite with TestScalaVersionArgs { this: TestScalaVersion => @@ -1007,4 +1008,37 @@ abstract class TestTestDefinitions extends ScalaCliSuite with TestScalaVersionAr } } } + + for { + javaVersion <- + if isScala38OrNewer then + Constants.allJavaVersions.filter(_ >= Constants.scala38MinJavaVersion) + else Constants.allJavaVersions.filter(_ < 24) + expectedMessage = "Hello, world!" + expectedWarning = s"Defaulting to a legacy test-runner module version" + } + test(s"run a simple test with Java $javaVersion") { + TestInputs(os.rel / "example.test.scala" -> + s"""//> using dep com.novocode:junit-interface:0.11 + |import org.junit.Test + | + |class MyTests { + | @Test + | def foo(): Unit = { + | assert(2 + 2 == 4) + | println("$expectedMessage") + | } + |} + |""".stripMargin).fromRoot { root => + val res = + os.proc(TestUtil.cli, "test", ".", extraOptions, "--jvm", javaVersion) + .call(cwd = root, stderr = os.Pipe) + val out = res.out.trim() + expect(out.contains(expectedMessage)) + if actualScalaVersion.startsWith("2") || javaVersion < Constants.scala38MinJavaVersion then + val err = res.err.trim() + expect(err.contains(expectedWarning)) + expect(err.countOccurrences(expectedWarning) == 1) + } + } } diff --git a/modules/options/src/main/scala/scala/build/Artifacts.scala b/modules/options/src/main/scala/scala/build/Artifacts.scala index 4800fc6658..c48f8646e0 100644 --- a/modules/options/src/main/scala/scala/build/Artifacts.scala +++ b/modules/options/src/main/scala/scala/build/Artifacts.scala @@ -128,6 +128,7 @@ object Artifacts { extraCompileOnlyJars: Seq[os.Path], extraSourceJars: Seq[os.Path], fetchSources: Boolean, + jvmVersion: Int, addJvmRunner: Option[Boolean], addJvmTestRunner: Boolean, addJmhDependencies: Option[String], @@ -146,11 +147,13 @@ object Artifacts { scalaVersion = scalaParams.scalaVersion } yield scalaVersion).getOrElse(defaultScalaVersion) + val shouldUseLegacyJava8Runners = jvmVersion < Constants.scala38MinJavaVersion val shouldUseLegacyScala3Runners = scalaVersion.startsWith("3") && scalaVersion.coursierVersion < s"$scala3LtsPrefix.0".coursierVersion val shouldUseLegacyScala2Runners = scalaVersion.startsWith("2") - val shouldUseLegacyRunners = shouldUseLegacyScala2Runners || shouldUseLegacyScala3Runners + val shouldUseLegacyScalaRunners = shouldUseLegacyScala3Runners || shouldUseLegacyScala2Runners + val shouldUseLegacyRunners = shouldUseLegacyScalaRunners || shouldUseLegacyJava8Runners val jvmTestRunnerDependencies = if addJvmTestRunner then { @@ -160,12 +163,25 @@ object Artifacts { else runnerScala2LegacyVersion val testRunnerVersion0 = if shouldUseLegacyRunners then { + if shouldUseLegacyScalaRunners then + logger.message( + s"$warnPrefix Scala $scalaVersion is no longer supported by the test-runner module." + ) + if shouldUseLegacyJava8Runners then + logger.message( + s"$warnPrefix Java $jvmVersion is no longer supported by the test-runner module." + ) logger.message( - s"""$warnPrefix Scala $scalaVersion is no longer supported by the test-runner module. - |$warnPrefix Defaulting to a legacy test-runner module version: $runnerLegacyVersion. - |$warnPrefix To use the latest test-runner, upgrade Scala to at least $scala3LtsPrefix.""" - .stripMargin + s"$warnPrefix Defaulting to a legacy test-runner module version: $runnerLegacyVersion." ) + if shouldUseLegacyScalaRunners then + logger.message( + s"$warnPrefix To use the latest test-runner, upgrade Scala to at least $scala3LtsPrefix." + ) + if shouldUseLegacyJava8Runners then + logger.message( + s"$warnPrefix To use the latest test-runner, upgrade Java to at least ${Constants.defaultJavaVersion}." + ) runnerLegacyVersion } else testRunnerVersion @@ -481,6 +497,25 @@ object Artifacts { if shouldUseLegacyScala3Runners then runnerScala30LegacyVersion else runnerScala2LegacyVersion + if shouldUseLegacyScalaRunners then + logger.message( + s"$warnPrefix Scala $scalaVersion is no longer supported by the runner module." + ) + if shouldUseLegacyJava8Runners then + logger.message( + s"$warnPrefix Java $jvmVersion is no longer supported by the runner module." + ) + logger.message( + s"$warnPrefix Defaulting to a legacy runner module version: $runnerLegacyVersion." + ) + if shouldUseLegacyScalaRunners then + logger.message( + s"$warnPrefix To use the latest runner, upgrade Scala to at least $scala3LtsPrefix." + ) + if shouldUseLegacyJava8Runners then + logger.message( + s"$warnPrefix To use the latest runner, upgrade Java to at least ${Constants.defaultJavaVersion}." + ) logger.message( s"""$warnPrefix Scala $scalaVersion is no longer supported by the runner module. |$warnPrefix Defaulting to a legacy runner module version: $runnerLegacyVersion. diff --git a/modules/options/src/main/scala/scala/build/options/BuildOptions.scala b/modules/options/src/main/scala/scala/build/options/BuildOptions.scala index 15b8192022..529ebedb68 100644 --- a/modules/options/src/main/scala/scala/build/options/BuildOptions.scala +++ b/modules/options/src/main/scala/scala/build/options/BuildOptions.scala @@ -464,7 +464,7 @@ final case class BuildOptions( } val extraRepositories: Seq[Repository] = value(finalRepositories) val maybeArtifacts = Artifacts( - scalaArtifactsParamsOpt, + scalaArtifactsParamsOpt = scalaArtifactsParamsOpt, javacPluginDependencies = value(javacPluginDependencies), extraJavacPlugins = javaOptions.javacPlugins.map(_.value), defaultDependencies = value(defaultDependencies), @@ -474,6 +474,7 @@ final case class BuildOptions( extraCompileOnlyJars = allExtraCompileOnlyJars, extraSourceJars = allExtraSourceJars, fetchSources = classPathOptions.fetchSources.getOrElse(false), + jvmVersion = javaHome().value.version, addJvmRunner = addRunnerDependency0, addJvmTestRunner = isTests && addJvmTestRunner, addJmhDependencies = jmhOptions.finalJmhVersion, diff --git a/project/deps/package.mill.scala b/project/deps/package.mill.scala index 8c10eb8a7d..f22e1c2590 100644 --- a/project/deps/package.mill.scala +++ b/project/deps/package.mill.scala @@ -90,6 +90,7 @@ object Scala { object Java { def minimumJavaLauncherJava = 11 def minimumBloopJava: Int = 17 + def minimumScala38Java: Int = 17 def minimumInternalJava: Int = 16 def defaultJava: Int = minimumBloopJava def cliKeyJavaVersions = Seq(