Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take into account JVM options defined in ~/.bloop/bloop.json #168

Merged
merged 6 commits into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ object BloopRifleConfig {
}

def default(
bloopClassPath: () => Either[Throwable, Seq[File]],
acceptBloopVersion: Option[String => Boolean]
bloopClassPath: () => Either[Throwable, Seq[File]]
): BloopRifleConfig =
BloopRifleConfig(
host = defaultHost,
port = defaultPort,
javaPath = "java",
javaOpts = defaultJavaOpts,
javaOpts =
defaultJavaOpts,
alexarchambault marked this conversation as resolved.
Show resolved Hide resolved
classPath = bloopClassPath,
bspSocketOrPort = None,
bspStdin = None,
Expand All @@ -104,6 +104,6 @@ object BloopRifleConfig {
startCheckPeriod = 100.millis,
startCheckTimeout = 1.minute,
initTimeout = 30.seconds,
acceptBloopVersion = acceptBloopVersion
acceptBloopVersion = None
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import scala.build.Ops._
class BuildTests extends munit.FunSuite {

val buildThreads = BuildThreads.create()
val bloopConfig = BloopRifleConfig.default(() => Bloop.bloopClassPath(Logger.nop), None)
val bloopConfig = BloopRifleConfig.default(() => Bloop.bloopClassPath(Logger.nop))

val extraRepoTmpDir = os.temp.dir(prefix = "scala-cli-tests-extra-repo-")
val directories = Directories.under(extraRepoTmpDir)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,13 @@
"allDeclaredMethods": true,
"allDeclaredFields": true
},
{
"name":"scala.cli.commands.BloopJson",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allDeclaredFields": true
},
{
"name":"com.google.cloud.tools.jib.cache.LayerEntriesSelector$LayerEntryTemplate",
"allDeclaredFields":true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package scala.cli.commands

import caseapp._
import com.google.gson.Gson
import coursier.core.Version

import java.io.File
import java.io.{BufferedReader, File, FileReader}
import java.nio.file.{AtomicMoveNotSupportedException, FileAlreadyExistsException, Files}
import java.util.Random

Expand All @@ -12,8 +13,7 @@ import scala.build.blooprifle.{BloopRifleConfig, BspConnectionAddress}
import scala.build.{Bloop, Logger, Os}
import scala.cli.internal.Pid
import scala.concurrent.duration.{Duration, FiniteDuration}
import scala.util.Properties

import scala.util.Properties;
alexarchambault marked this conversation as resolved.
Show resolved Hide resolved

// format: off
final case class SharedCompilationServerOptions(
Expand Down Expand Up @@ -58,7 +58,10 @@ final case class SharedCompilationServerOptions(
@Group("Compilation server")
bloopDefaultJavaOpts: Boolean = true,
@Group("Compilation server")
bloopJavaOpt: List[String] = Nil
bloopJavaOpt: List[String] = Nil,
@Group("Compilation server")
@HelpMessage("Bloop global options file")
bloopGlobalOptionsFile: String = (os.home / ".bloop" / "bloop.json").toNIO.toAbsolutePath().toString(),
alexarchambault marked this conversation as resolved.
Show resolved Hide resolved
) {
// format: on

Expand Down Expand Up @@ -160,14 +163,36 @@ final case class SharedCompilationServerOptions(
def minimumBloopVersion = Constants.bloopVersion
def acceptBloopVersion = Some((v: String) => Version(v) < Version(minimumBloopVersion))

def bloopDefaultJvmOptions(logger: Logger): List[String] = {
val file = new File(bloopGlobalOptionsFile)
if (file.exists() && file.isFile()) {
try {
val reader = new BufferedReader(new FileReader(file))
val gson = new Gson()
alexarchambault marked this conversation as resolved.
Show resolved Hide resolved
val json = gson.fromJson(reader, classOf[BloopJson])
json.javaOptions.toList
}
catch {
case e: Throwable => {
e.printStackTrace()
List.empty
}
}
}
else {
logger.debug(s"Bloop global options file '${file.toPath().toAbsolutePath()}' not found.")
List.empty
}
}

def bloopRifleConfig(
logger: Logger,
verbosity: Int,
javaPath: String,
directories: => scala.build.Directories
): BloopRifleConfig = {
val baseConfig =
BloopRifleConfig.default(() => Bloop.bloopClassPath(logger), acceptBloopVersion)
BloopRifleConfig.default(() => Bloop.bloopClassPath(logger))
val portOpt = bloopPort.filter(_ != 0) match {
case Some(n) if n < 0 =>
Some(scala.build.blooprifle.internal.Util.randomPort())
Expand All @@ -183,13 +208,17 @@ final case class SharedCompilationServerOptions(
period = bloopBspCheckPeriodDuration.getOrElse(baseConfig.period),
timeout = bloopBspTimeoutDuration.getOrElse(baseConfig.timeout),
initTimeout = bloopStartupTimeoutDuration.getOrElse(baseConfig.initTimeout),
javaOpts = (if (bloopDefaultJavaOpts) baseConfig.javaOpts else Nil) ++ bloopJavaOpt
javaOpts =
(if (bloopDefaultJavaOpts) baseConfig.javaOpts
else Nil) ++ bloopJavaOpt ++ bloopDefaultJvmOptions(logger),
acceptBloopVersion = acceptBloopVersion
)
}

}

object SharedCompilationServerOptions {
implicit val parser = Parser[SharedCompilationServerOptions]
implicit val help = Help[SharedCompilationServerOptions]
}

case class BloopJson(javaHome: String, javaOptions: Array[String])
alexarchambault marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -303,25 +303,24 @@ abstract class BspTestDefinitions(val scalaVersionOpt: Option[String])
}
}

def runScalaCli(args: String*) = os.proc(TestUtil.cli, args)

def testScalaTermination(
currentBloopVersion: String,
expectedBloopVersionAfterScalaCliRun: String
): Unit =
TestUtil.retry() {
alexarchambault marked this conversation as resolved.
Show resolved Hide resolved
def runBloop(args: String*) =
os.proc(TestUtil.cs, "launch", s"bloop-jvm:$currentBloopVersion", "--", args)

def runScalaCli(args: String*) = os.proc(TestUtil.cli, args)

runBloop("exit").call()
runBloop("about").call(stdout = os.Inherit, stderr = os.Inherit)
runScalaCli("bloop", "start", "-v", "-v", "-v").call(
stdout = os.Inherit,
stderr = os.Inherit
)
val versionLine = runBloop("about").call().out.lines()(0)
expect(versionLine == "bloop v" + expectedBloopVersionAfterScalaCliRun)
}
) = {
def runBloop(args: String*) =
os.proc(TestUtil.cs, "launch", s"bloop-jvm:$currentBloopVersion", "--", args)

runBloop("exit").call()
runBloop("about").call(stdout = os.Inherit, stderr = os.Inherit)
runScalaCli("bloop", "start", "-v", "-v", "-v").call(
stdout = os.Inherit,
stderr = os.Inherit
)
val versionLine = runBloop("about").call().out.lines()(0)
expect(versionLine == "bloop v" + expectedBloopVersionAfterScalaCliRun)
}

test("scala-cli terminates incompatible bloop") {
testScalaTermination(Constants.oldBloopVersion, Constants.bloopVersion)
Expand All @@ -331,6 +330,44 @@ abstract class BspTestDefinitions(val scalaVersionOpt: Option[String])
testScalaTermination(Constants.newBloopVersion, Constants.newBloopVersion)
}

test("invalid bloop options passed via cli cause bloop start failure") {
runScalaCli("bloop", "exit").call()
val res = runScalaCli("bloop", "start", "--bloop-java-opt", "-Xmx1k").call(
stderr = os.Pipe,
check = false
)
expect(res.exitCode == 1)
expect(res.err.text().contains("Server didn't start") || res.err.text().contains(
"java.lang.OutOfMemoryError: Garbage-collected heap size exceeded"
))
}

test("invalid bloop options passed via global bloop config json file cause bloop start failure") {
val inputs = TestInputs(
Seq(
os.rel / "bloop.json" ->
"""|{
| "javaOptions" : ["-Xmx1k"]
| }""".stripMargin
)
)

inputs.fromRoot { root =>
runScalaCli("bloop", "exit").call()
val res = runScalaCli(
"bloop",
"start",
"--bloop-global-options-file",
(root / "bloop.json").toString()
)
.call(stderr = os.Pipe, check = false)
expect(res.exitCode == 1)
expect(res.err.text().contains("Server didn't start") || res.err.text().contains(
"java.lang.OutOfMemoryError: Garbage-collected heap size exceeded"
))
}
}

test("diagnostics") {
val inputs = TestInputs(
Seq(
Expand Down
4 changes: 4 additions & 0 deletions website/docs/reference/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ Maximum duration to wait for compilation server to start up

#### `--bloop-java-opt`

#### `--bloop-global-options-file`

Bloop global options file

## Compile options

Available in commands:
Expand Down