Skip to content

Commit

Permalink
Ensure -release works without -O, redirect it to --jvm, handle …
Browse files Browse the repository at this point in the history
…ambiguities and make it Scala version independent
  • Loading branch information
Gedochao committed Oct 4, 2022
1 parent 847ea8f commit 5b024df
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ object ScalacOptions {
private val scalacOptionsPrefixes =
Set("-g", "-language", "-opt", "-P", "-target") ++ scalacOptionsPurePrefixes
private val scalacAliasedOptions = // these options don't require being passed after -O
Set("-encoding")
Set("-encoding", "-release")

/** This includes all the scalac options which disregard inputs and print a help and/or context
* message instead.
Expand All @@ -46,7 +46,8 @@ object ScalacOptions {
/** This includes all the scalac options which are redirected to native Scala CLI options. */
val ScalaCliRedirectedOptions = Set(
"-classpath", // redirected to --extra-jars
"-d" // redirected to --compilation-output
"-d", // redirected to --compilation-output
"-release" // redirected to --jvm
)

private val scalacOptionsArgument: Argument[List[String]] =
Expand Down
20 changes: 17 additions & 3 deletions modules/cli/src/main/scala/scala/cli/commands/util/JvmUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ package util
import java.io.File

import scala.build.EitherCps.{either, value}
import scala.build.errors.{BuildException, UnrecognizedDebugModeError}
import scala.build.errors.{AmbiguousJvmError, BuildException, UnrecognizedDebugModeError}
import scala.build.options.{JavaOpt, JavaOptions, ShadowingSeq}
import scala.build.{Os, Position, Positioned}
import scala.cli.commands.util.ScalacOptionsUtil.*
import scala.util.Properties

object JvmUtils {
def javaOptions(opts: SharedJvmOptions): Either[BuildException, JavaOptions] = either {
def javaOptions(
opts: SharedJvmOptions,
scalacOpts: List[String] = List.empty
): Either[BuildException, JavaOptions] = either {
import opts._

val (javacFilePlugins, javacPluginDeps) =
Expand Down Expand Up @@ -44,11 +48,21 @@ object JvmUtils {
Seq.empty
}

val jvmIdOpt: Option[String] = value {
jvm -> scalacOpts.toScalacOptShadowingSeq.getScalacOption("-release") match {
case (Some(j1), Some(j2)) if j1 == j2 => Right(Some(j1))
case (Some(j1), Some(j2)) => Left(AmbiguousJvmError(Seq(j1, j2)))
case (Some(j), _) => Right(Some(j))
case (_, Some(j)) => Right(Some(j))
case _ => Right(None)
}
}

JavaOptions(
javaHomeOpt = javaHome.filter(_.nonEmpty).map(v =>
Positioned(Seq(Position.CommandLine("--java-home")), os.Path(v, Os.pwd))
),
jvmIdOpt = jvm.filter(_.nonEmpty),
jvmIdOpt = jvmIdOpt.filter(_.nonEmpty),
jvmIndexOpt = jvmIndex.filter(_.nonEmpty),
jvmIndexOs = jvmIndexOs.map(_.trim).filter(_.nonEmpty),
jvmIndexArch = jvmIndexArch.map(_.trim).filter(_.nonEmpty),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ object SharedOptionsUtil extends CommandHelpers {
),
scalaJsOptions = scalaJsOptions(js),
scalaNativeOptions = scalaNativeOptions(native),
javaOptions = value(scala.cli.commands.util.JvmUtils.javaOptions(jvm)),
javaOptions = value(scala.cli.commands.util.JvmUtils.javaOptions(jvm, scalac.scalacOption)),
internalDependencies = bo.InternalDependenciesOptions(
addStubsDependencyOpt = addStubs,
addRunnerDependencyOpt = runner
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package scala.build.errors

case class AmbiguousJvmError(passedJVMs: Seq[String]) extends BuildException(
s"Ambiguous JVM, more than one JVM have been passed: ${passedJVMs.sorted.mkString(", ")}."
)
Original file line number Diff line number Diff line change
Expand Up @@ -242,25 +242,6 @@ abstract class CompileTestDefinitions(val scalaVersionOpt: Option[String])
)
}

test("Scala CLI should not infer scalac's--release if 'O --release' is passed".tag(jvmT)) {
scalaJvm11Project.fromRoot { root =>
val res = os.proc(
TestUtil.cli,
"compile",
extraOptions,
"--jvm",
"11",
"-O",
"-release",
"-O",
"8",
"."
).call(cwd = root, check = false, stderr = os.Pipe)
expect(res.exitCode != 0)
expect(res.err.text().contains("isEmpty is not a member"))
}
}

def compileToADifferentJvmThanBloops(
bloopJvm: String,
targetJvm: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2555,4 +2555,40 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
expect(res.out.trim == "")
}
}

test("different jvm values passed to --jvm and -release should produce an error message") {
TestInputs(os.rel / "s.sc" -> """println("Hello")""")
.fromRoot { root =>
val res = os.proc(
TestUtil.cli,
"s.sc",
"-release",
"8",
"--jvm",
"11",
extraOptions
).call(cwd = root, check = false, stderr = os.Pipe)
val expectedError =
s"[${Console.RED}error${Console.RESET}] Ambiguous JVM, more than one JVM have been passed: 11, 8."
expect(res.err.trim == expectedError)
}
}

test("-release allows to set the JVM on par with --jvm") {
val expectedMsg = "Hello"
TestInputs(os.rel / "s.sc" ->
s"""import java.net.http.HttpRequest
|println("$expectedMsg")""".stripMargin)
.fromRoot { root =>
val res8 = os.proc(TestUtil.cli, "s.sc", "-release", "8", extraOptions)
.call(cwd = root, check = false, stderr = os.Pipe)
expect(res8.exitCode == 1)
val res8jvm = os.proc(TestUtil.cli, "s.sc", "--jvm", "8", extraOptions)
.call(cwd = root, check = false, stderr = os.Pipe)
expect(res8.err.trim == res8jvm.err.trim)
val res11 = os.proc(TestUtil.cli, "s.sc", "-release", "11", extraOptions)
.call(cwd = root)
expect(res11.out.trim == expectedMsg)
}
}
}

0 comments on commit 5b024df

Please sign in to comment.