Skip to content

Commit

Permalink
Send the Bloop server output to a file when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
alexarchambault committed Apr 5, 2022
1 parent 5bbcfc2 commit 661dce8
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,25 @@ object BloopRifle {
): Future[Unit] =
config.classPath(version) match {
case Left(ex) => Future.failed(new Exception("Error getting Bloop class path", ex))
case Right(cp) =>
case Right((cp, isScalaCliBloop)) =>
object IntValue {
def unapply(s: String): Option[Int] =
// no String.toIntOption in Scala 2.12.x
try Some(s.toInt)
catch {
case _: NumberFormatException => None
}
}
val bloopServerSupportsFileTruncating =
isScalaCliBloop && {
version.takeWhile(c => c.isDigit || c == '.').split('.') match {
case Array(IntValue(maj), IntValue(min), IntValue(patch)) =>
import scala.math.Ordering.Implicits._
Seq(maj, min, patch) >= Seq(1, 14, 20)
case _ =>
false
}
}
Operations.startServer(
config.address,
bloopJava,
Expand All @@ -57,7 +75,8 @@ object BloopRifle {
scheduler,
config.startCheckPeriod,
config.startCheckTimeout,
logger
logger,
bloopServerSupportsFileTruncating = bloopServerSupportsFileTruncating
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ final case class BloopRifleConfig(
address: BloopRifleConfig.Address,
javaPath: String,
javaOpts: Seq[String],
classPath: String => Either[Throwable, Seq[File]],
classPath: String => Either[Throwable, (Seq[File], Boolean)],
workingDir: File,
bspSocketOrPort: Option[() => BspConnectionAddress],
bspStdin: Option[InputStream],
Expand All @@ -38,6 +38,8 @@ object BloopRifleConfig {
}
final case class DomainSocket(path: Path) extends Address {
def render = path.toString
def outputPath: Path =
path.resolve("output")
}
}

Expand Down Expand Up @@ -87,8 +89,9 @@ object BloopRifleConfig {
.getOrElse(hardCodedDefaultJavaOpts)
}

def scalaCliBloopOrg = "io.github.alexarchambault.bleep"
def hardCodedDefaultModule: String =
"io.github.alexarchambault.bleep:bloop-frontend_2.12"
s"$scalaCliBloopOrg:bloop-frontend_2.12"
def hardCodedDefaultVersion: String =
Constants.bloopVersion
def hardCodedDefaultScalaVersion: String =
Expand Down Expand Up @@ -118,7 +121,7 @@ object BloopRifleConfig {

def default(
address: Address,
bloopClassPath: String => Either[Throwable, Seq[File]],
bloopClassPath: String => Either[Throwable, (Seq[File], Boolean)],
workingDir: File
): BloopRifleConfig =
BloopRifleConfig(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,28 @@ object Operations {
scheduler: ScheduledExecutorService,
waitInterval: FiniteDuration,
timeout: Duration,
logger: BloopRifleLogger
logger: BloopRifleLogger,
bloopServerSupportsFileTruncating: Boolean
): Future[Unit] = {

val (addressArgs, mainClass) = address match {
val (addressArgs, mainClass, writeOutputToOpt) = address match {
case BloopRifleConfig.Address.Tcp(host, port) =>
(Seq(host, port.toString), "bloop.Server")
case BloopRifleConfig.Address.DomainSocket(path) =>
(Seq(s"daemon:$path"), "bloop.Bloop")
(Seq(host, port.toString), "bloop.Server", None)
case s: BloopRifleConfig.Address.DomainSocket =>
val writeOutputToOpt0 =
if (bloopServerSupportsFileTruncating) Some(s.outputPath)
else None
(Seq(s"daemon:${s.path}"), "bloop.Bloop", writeOutputToOpt0)
}

val extraJavaOpts =
writeOutputToOpt.toSeq.map { writeOutputTo =>
s"-Dbloop.truncate-output-file-periodically=${writeOutputTo.toAbsolutePath}"
}

val command =
Seq(javaPath) ++
extraJavaOpts ++
javaOpts ++
Seq(
"-cp",
Expand All @@ -117,15 +128,25 @@ object Operations {
b.directory(workingDir)
b.redirectInput(ProcessBuilder.Redirect.PIPE)

b.redirectOutput {
if (logger.bloopCliInheritStdout) ProcessBuilder.Redirect.INHERIT
else ProcessBuilder.Redirect.DISCARD
}
if (logger.bloopCliInheritStdout)
b.redirectOutput(ProcessBuilder.Redirect.INHERIT)
else
writeOutputToOpt match {
case Some(writeOutputTo) =>
b.redirectOutput(writeOutputTo.toFile)
case None =>
b.redirectOutput(ProcessBuilder.Redirect.DISCARD)
}

b.redirectError {
if (logger.bloopCliInheritStderr) ProcessBuilder.Redirect.INHERIT
else ProcessBuilder.Redirect.DISCARD
}
if (logger.bloopCliInheritStderr)
b.redirectError(ProcessBuilder.Redirect.INHERIT)
else
writeOutputToOpt match {
case Some(writeOutputTo) =>
b.redirectError(writeOutputTo.toFile)
case None =>
b.redirectError(ProcessBuilder.Redirect.DISCARD)
}

val p = b.start()
p.getOutputStream.close()
Expand Down
19 changes: 12 additions & 7 deletions modules/build/src/main/scala/scala/build/Bloop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,28 @@ object Bloop {
res.map(_._2.toIO)
}

def bloopClassPath(logger: Logger, cache: FileCache[Task]): Either[BuildException, Seq[File]] =
def bloopClassPath(
logger: Logger,
cache: FileCache[Task]
): Either[BuildException, (Seq[File], Boolean)] =
bloopClassPath(logger, cache, BloopRifleConfig.defaultVersion)

def bloopClassPath(
logger: Logger,
cache: FileCache[Task],
bloopVersion: String
): Either[BuildException, Seq[File]] = either {
): Either[BuildException, (Seq[File], Boolean)] = either {
val moduleStr = BloopRifleConfig.defaultModule
val mod = value {
ModuleParser.parse(moduleStr)
.left.map(err => new ModuleFormatError(moduleStr, err, Some("Bloop")))
}
val dep = DependencyLike(mod, bloopVersion)
val sv = BloopRifleConfig.defaultScalaVersion
val sbv = ScalaVersion.binary(sv)
val params = ScalaParameters(sv, sbv)
value(bloopClassPath(dep, params, logger, cache))
val dep = DependencyLike(mod, bloopVersion)
val sv = BloopRifleConfig.defaultScalaVersion
val sbv = ScalaVersion.binary(sv)
val params = ScalaParameters(sv, sbv)
val cp = value(bloopClassPath(dep, params, logger, cache))
val isScalaCliBloop = moduleStr.startsWith(BloopRifleConfig.scalaCliBloopOrg + ":")
(cp, isScalaCliBloop)
}
}

0 comments on commit 661dce8

Please sign in to comment.