Skip to content

Commit

Permalink
Merge pull request scala#14073 from BarkingBad/passing-jvm-opts-to-scala
Browse files Browse the repository at this point in the history
Fix passing jvm options
  • Loading branch information
BarkingBad authored Dec 13, 2021
2 parents 472c8ff + 2d70b59 commit dcb123d
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ jobs:

- name: Cmd Tests
run: |
./project/scripts/sbt ";scala3-bootstrapped/compile; scala3-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test;sjsCompilerTests/test ;sbt-test/scripted scala2-compat/* ;configureIDE ;stdlib-bootstrapped/test:run ;stdlib-bootstrapped-tasty-tests/test; scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test"
./project/scripts/sbt ";dist/pack; scala3-bootstrapped/compile; scala3-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test;sjsCompilerTests/test ;sbt-test/scripted scala2-compat/* ;configureIDE ;stdlib-bootstrapped/test:run ;stdlib-bootstrapped-tasty-tests/test; scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test"
./project/scripts/bootstrapCmdTests
- name: MiMa
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/MainGenericRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ object MainGenericRunner {
process(tail, newSettings.withResidualArgs(arg))

def main(args: Array[String]): Unit =
val scalaOpts = envOrNone("SCALA_OPTS").toArray.flatMap(_.split(" "))
val scalaOpts = envOrNone("SCALA_OPTS").toArray.flatMap(_.split(" ")).filter(_.nonEmpty)
val allArgs = scalaOpts ++ args
val settings = process(allArgs.toList, Settings())
if settings.exitCode != 0 then System.exit(settings.exitCode)
Expand Down
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ trait AllScalaSettings extends CommonScalaSettings, PluginSettings, VerboseSetti
)

val wikiSyntax: Setting[Boolean] = BooleanSetting("-Xwiki-syntax", "Retains the Scala2 behavior of using Wiki Syntax in Scaladoc.")

val jvmargs = PrefixSetting("-J<flag>", "-J", "Pass <flag> directly to the runtime system.")
val defines = PrefixSetting("-Dproperty=value", "-D", "Pass -Dproperty=value directly to the runtime system.")
end AllScalaSettings

/** Settings shared by compiler and scaladoc */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ class CoursierScalaTests:
assertTrue(output.mkString("\n").endsWith("scriptPath.sc"))
scriptPath()

def scriptEnvDashJDashD() =
val scriptPath = scripts("/scripting").find(_.getName == "envtest.sc").get.absPath
val args = scriptPath
val output = CoursierScalaTests.csScalaCmd("-J-Dkey=World", args)
assertEquals(output.mkString("\n"), "Hello World")
scriptEnvDashJDashD()

def version() =
val output = CoursierScalaTests.csScalaCmd("-version")
assertTrue(output.mkString("\n").contains(sys.env("DOTTY_BOOTSTRAPPED_VERSION")))
Expand All @@ -75,6 +82,11 @@ class CoursierScalaTests:
assertEquals(output.mkString("\n"), "Hello")
run()

def runDashJDashD() =
val output = CoursierScalaTests.csScalaCmd("-J-Dkey=World", "-classpath", scripts("/run").head.getParentFile.getParent, "-run", "run.envtest")
assertEquals(output.mkString("\n"), "Hello World")
runDashJDashD()

def notOnlyOptionsEqualsRun() =
val output = CoursierScalaTests.csScalaCmd("-classpath", scripts("/run").head.getParentFile.getParent, "run.myfile")
assertEquals(output.mkString("\n"), "Hello")
Expand Down Expand Up @@ -147,10 +159,12 @@ object CoursierScalaTests:
csCmd("dotty.tools.dotc.Main", options*)

private def csCmd(entry: String, options: String*): List[String] =
val newOptions = options match
case Nil => options
case _ => "--" +: options
execCmd("./cs", (s"""launch "org.scala-lang:scala3-compiler_3:${sys.env("DOTTY_BOOTSTRAPPED_VERSION")}" --main-class "$entry" --property "scala.usejavacp=true"""" +: newOptions)*)
val (jOpts, args) = options.partition(_.startsWith("-J"))
val newOptions = args match
case Nil => args
case _ => "--" +: args
val newJOpts = jOpts.map(s => s"--java-opt ${s.stripPrefix("-J")}").mkString(" ")
execCmd("./cs", (s"""launch "org.scala-lang:scala3-compiler_3:${sys.env("DOTTY_BOOTSTRAPPED_VERSION")}" $newJOpts --main-class "$entry" --property "scala.usejavacp=true"""" +: newOptions)*)

/** Get coursier script */
@BeforeClass def setup(): Unit =
Expand Down
4 changes: 4 additions & 0 deletions compiler/test-coursier/run/envtest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package run

object envtest extends App:
println("Hello " + sys.props("key"))
2 changes: 1 addition & 1 deletion compiler/test-resources/scripting/classpathReport.sc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!dist/target/pack/bin/scala -classpath dist/target/pack/lib/*
#!/usr/bin/env -S bin/scala -classpath 'dist/target/pack/lib/*'

import java.nio.file.Paths

Expand Down
2 changes: 2 additions & 0 deletions compiler/test-resources/scripting/envtest.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def main(args: Array[String]): Unit =
println("Hello " + util.Properties.propOrNull("key"))
4 changes: 4 additions & 0 deletions compiler/test-resources/scripting/envtest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package run

object envtest extends App:
println("Hello " + sys.props("key"))
2 changes: 1 addition & 1 deletion compiler/test-resources/scripting/unglobClasspath.sc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!bin/scala -classpath 'dist/target/pack/lib/*'
#!/usr/bin/env -S bin/scala -classpath 'dist/target/pack/lib/*'

// won't compile unless the hashbang line sets classpath
import org.jline.terminal.Terminal
Expand Down
66 changes: 49 additions & 17 deletions compiler/test/dotty/tools/scripting/BashScriptsTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import java.nio.file.{Path, Paths, Files}
import scala.sys.process._

import org.junit.Test
import org.junit.Assert.assertEquals

import vulpix.TestConfiguration

Expand All @@ -28,13 +29,13 @@ class BashScriptsTests:
printf("scalac path: [%s]\n", scalacPath)

lazy val expectedOutput = List(
"arg 0:[a]",
"arg 1:[b]",
"arg 2:[c]",
"arg 3:[-repl]",
"arg 4:[-run]",
"arg 5:[-script]",
"arg 6:[-debug]",
"arg 0:[a]",
"arg 1:[b]",
"arg 2:[c]",
"arg 3:[-repl]",
"arg 4:[-run]",
"arg 5:[-script]",
"arg 6:[-debug]",
)
lazy val testScriptArgs = Seq(
"a", "b", "c", "-repl", "-run", "-script", "-debug"
Expand All @@ -56,6 +57,38 @@ class BashScriptsTests:
if fail then
assert(stdout == expectedOutput)

/* verify `dist/bin/scala` with -J setting */
@Test def verifyScJProperty =
val commandline = Seq(scalaPath, "-J-Dkey=World", testFiles.find(_.getName == "envtest.sc").get.absPath).mkString(" ")
val (validTest, exitCode, stdout, stderr) = bashCommand(commandline)
assertEquals(stdout.mkString("/n"), "Hello World")

/* verify `dist/bin/scala` with -J setting */
@Test def verifyScalaJProperty =
val commandline = Seq(scalaPath, "-J-Dkey=World3", testFiles.find(_.getName == "envtest.scala").get.absPath).mkString(" ")
val (validTest, exitCode, stdout, stderr) = bashCommand(commandline)
assertEquals(stdout.mkString("/n"), "Hello World3")

/* verify `dist/bin/scala` with -D setting */
@Test def verifyScDProperty =
val commandline = Seq(scalaPath, "-Dkey=World3", testFiles.find(_.getName == "envtest.sc").get.absPath).mkString(" ")
val (validTest, exitCode, stdout, stderr) = bashCommand(commandline)
assertEquals(stdout.mkString("/n"), "Hello World3")

/* verify `dist/bin/scala` with -D setting */
@Test def verifyScalaDProperty =
val commandline = Seq(scalaPath, "-Dkey=World4", testFiles.find(_.getName == "envtest.scala").get.absPath).mkString(" ")
val (validTest, exitCode, stdout, stderr) = bashCommand(commandline)
assertEquals(stdout.mkString("/n"), "Hello World4")

/* verify `dist/bin/scala` with -D setting */
@Test def saveAndRunWithDProperty =
val commandline = Seq(scalaPath, "-save", testFiles.find(_.getName == "envtest.scala").get.absPath).mkString(" ")
val (_, _, _, _) = bashCommand(commandline)
val commandline2 = Seq(scalaPath, "-Dkey=World5", testFiles.find(_.getName == "envtest.jar").get.absPath).mkString(" ")
val (validTest, exitCode, stdout, stderr) = bashCommand(commandline2)
assertEquals(stdout.mkString("/n"), "Hello World5")

/* verify `dist/bin/scala` non-interference with command line args following script name */
@Test def verifyScalaArgs =
val commandline = (Seq("SCALA_OPTS= ", scalaPath, showArgsScript) ++ testScriptArgs).mkString(" ")
Expand All @@ -73,7 +106,7 @@ class BashScriptsTests:
assert(stdout == expectedOutput)

/*
* verify that scriptPath.sc sees a valid script.path property,
* verify that scriptPath.sc sees a valid script.path property,
* and that it's value is the path to "scriptPath.sc".
*/
@Test def verifyScriptPathProperty =
Expand Down Expand Up @@ -134,6 +167,7 @@ class BashScriptsTests:
def exists: Boolean = s.toPath.toFile.exists
def name: String = s.toFile.getName
def dropExtension: String = s.reverse.dropWhile(_ != '.').drop(1).reverse
def parent(up: Int): String = s.norm.split("/").reverse.drop(up).reverse.mkString("/")
}

extension(p: Path) {
Expand Down Expand Up @@ -168,22 +202,20 @@ class BashScriptsTests:
if scalacPath.isFile then scalacPath.replaceAll("/bin/scalac", "")
else envOrElse("SCALA_HOME", "").norm

lazy val javaHome = envOrElse("JAVA_HOME", "").norm
lazy val javaHome = whichJava.parent(2)

lazy val testEnvPairs = List(
("JAVA_HOME", javaHome),
("SCALA_HOME", scalaHome),
("PATH", adjustedPath),
).filter { case (name, valu) => valu.nonEmpty }

lazy val whichBash: String =
var whichBash = ""
if osname.startsWith("windows") then
whichBash = which("bash.exe")
else
whichBash = which("bash")
lazy val whichBash: String = whichExe("bash")
lazy val whichJava: String = whichExe("java")

whichBash
def whichExe(basename: String): String =
val exeName = if (osname.toLowerCase.startsWith("windows")) s"$basename.exe" else basename
which(exeName)

def bashCommand(cmdstr: String, additionalEnvPairs: List[(String, String)] = Nil): (Boolean, Int, Seq[String], Seq[String]) = {
var (stdout, stderr) = (List.empty[String], List.empty[String])
Expand All @@ -192,7 +224,7 @@ class BashScriptsTests:
val envPairs = testEnvPairs ++ additionalEnvPairs
val proc = Process(cmd, None, envPairs *)
val exitVal = proc ! ProcessLogger (
(out: String) => stdout ::= out,
(out: String) => stdout ::= out,
(err: String) => stderr ::= err
)
val validTest = exitVal == 0 && ! stderr.exists(_.contains("Permission denied"))
Expand Down
6 changes: 3 additions & 3 deletions compiler/test/dotty/tools/scripting/ClasspathTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ class ClasspathTests:

cmd.foreach { printf("[%s]\n", _) }

// test script reports the classpath it sees
// test script reports the classpath it sees
val scriptOutput = exec(cmd:_*)
val scriptCwd = findTaggedLine("cwd", scriptOutput)
printf("script ran in directory [%s]\n", scriptCwd)
val scriptCp = findTaggedLine("classpath", scriptOutput)

val hashbangClasspathJars = scriptCp.split(psep).map { _.getName }.sorted.distinct
val packlibJars = listJars(s"$scriptCwd/$packLibDir").sorted.distinct

printf("%d jar files in dist/target/pack/lib\n", packlibJars.size)
printf("%d test script jars in classpath\n", hashbangClasspathJars.size)

Expand Down Expand Up @@ -78,7 +78,7 @@ class ClasspathTests:

cmd.foreach { printf("[%s]\n", _) }

// test script reports the classpath it sees
// test script reports the classpath it sees
val scriptOutput = exec(cmd:_*)
val scriptCp = findTaggedLine("unglobbed classpath", scriptOutput)
val classpathJars = scriptCp.split(psep).map { _.getName }.sorted.distinct
Expand Down
26 changes: 25 additions & 1 deletion dist/bin/scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,34 @@ fi

source "$PROG_HOME/bin/common"

while [[ $# -gt 0 ]]; do
case "$1" in
-D*)
# pass to scala as well: otherwise we lose it sometimes when we
# need it, e.g. communicating with a server compiler.
addJava "$1"
addScala "$1"
# respect user-supplied -Dscala.usejavacp
shift
;;
-J*)
# as with -D, pass to scala even though it will almost
# never be used.
addJava "${1:2}"
addScala "$1"
shift
;;
*)
addScala "$1"
shift
;;
esac
done

# exec here would prevent onExit from being called, leaving terminal in unusable state
compilerJavaClasspathArgs
[ -z "${ConEmuPID-}" -o -n "${cygwin-}" ] && export MSYSTEM= PWD= # workaround for #12405
eval "\"$JAVACMD\"" "-Dscala.home=$PROG_HOME" "-classpath \"$jvm_cp_args\"" "dotty.tools.MainGenericRunner" "-classpath \"$jvm_cp_args\"" "$@"
eval "\"$JAVACMD\"" "${java_args[@]}" "-Dscala.home=$PROG_HOME" "-classpath \"$jvm_cp_args\"" "dotty.tools.MainGenericRunner" "-classpath \"$jvm_cp_args\"" "${scala_args[@]}"
scala_exit_status=$?


Expand Down

0 comments on commit dcb123d

Please sign in to comment.