From fa0b63e37dff08e2f1feed9c221a27e93134e332 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 07:50:58 +0200 Subject: [PATCH 01/24] Revise system streams handling in BSP mode --- runner/src/mill/runner/MillMain.scala | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index fd1b2b6b73d..92d5ebf694b 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -16,16 +16,26 @@ object MillMain { def main(args: Array[String]): Unit = { val initialSystemStreams = new SystemStreams(System.out, System.err, System.in) // setup streams - val openStreams = + val (runnerStreams, openStreams) = if (args.headOption == Option("--bsp")) { + // In BSP mode, we use System.in for protocol communication + // and all Mill output goes to a dedicated file val stderrFile = os.pwd / ".bsp" / "mill-bsp.stderr" os.makeDir.all(stderrFile / os.up) + val msg = s"Mill in BSP mode, version ${BuildInfo.millVersion}, ${new java.util.Date()}" + System.err.println(msg) val err = new PrintStream(new FileOutputStream(stderrFile.toIO, true)) - System.setErr(err) System.setOut(err) - err.println(s"Mill in BSP mode, version ${BuildInfo.millVersion}, ${new java.util.Date()}") - Seq(err) - } else Seq() + System.setErr(err) + err.println(msg) + ( + new SystemStreams(initialSystemStreams.out, System.err, System.in), + Seq(err) + ) + } else { + // Unchanged system stream + (initialSystemStreams, Seq()) + } if (Properties.isWin && System.console() != null) io.github.alexarchambault.windowsansi.WindowsAnsi.setup() @@ -35,7 +45,7 @@ object MillMain { args, RunnerState.empty, mill.util.Util.isInteractive(), - initialSystemStreams, + runnerStreams, System.getenv().asScala.toMap, b => (), userSpecifiedProperties0 = Map(), From cb698a257a3f8938ed3474459c9954ad4fcf9fa6 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 08:30:51 +0200 Subject: [PATCH 02/24] Use a tee output stream to copy stderr output into file --- runner/src/mill/runner/MillMain.scala | 17 ++--- runner/src/mill/runner/TeeOutputStream.scala | 66 ++++++++++++++++++++ 2 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 runner/src/mill/runner/TeeOutputStream.scala diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index 92d5ebf694b..f1ea94b9bee 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -19,18 +19,19 @@ object MillMain { val (runnerStreams, openStreams) = if (args.headOption == Option("--bsp")) { // In BSP mode, we use System.in for protocol communication - // and all Mill output goes to a dedicated file + // and all Mill output (stdout and stderr) goes to a dedicated file val stderrFile = os.pwd / ".bsp" / "mill-bsp.stderr" os.makeDir.all(stderrFile / os.up) val msg = s"Mill in BSP mode, version ${BuildInfo.millVersion}, ${new java.util.Date()}" - System.err.println(msg) - val err = new PrintStream(new FileOutputStream(stderrFile.toIO, true)) - System.setOut(err) - System.setErr(err) - err.println(msg) +// System.err.println(msg) + val errFile = new PrintStream(new FileOutputStream(stderrFile.toIO, true)) + val errTee = new TeePrintOutputStream(initialSystemStreams.err, errFile) + System.setOut(errFile) + System.setErr(errTee) + errTee.println(msg) ( - new SystemStreams(initialSystemStreams.out, System.err, System.in), - Seq(err) + new SystemStreams(initialSystemStreams.out, errTee, System.in), + Seq(errFile) ) } else { // Unchanged system stream diff --git a/runner/src/mill/runner/TeeOutputStream.scala b/runner/src/mill/runner/TeeOutputStream.scala new file mode 100644 index 00000000000..66c006c1ac8 --- /dev/null +++ b/runner/src/mill/runner/TeeOutputStream.scala @@ -0,0 +1,66 @@ +package mill.runner + +import java.io.{OutputStream, PrintStream} + +class TeeOutputStream(out1: OutputStream, out2: OutputStream) extends OutputStream { + override def write(b: Int): Unit = synchronized { + out1.write(b) + out2.write(b) + } + + override def write(b: Array[Byte]): Unit = synchronized { + out1.write(b) + out2.write(b) + } + + override def write(b: Array[Byte], off: Int, len: Int): Unit = synchronized { + out1.write(b, off, len) + out2.write(b, off, len) + } + + override def flush(): Unit = { + out1.flush() + out2.flush() + } + + override def close(): Unit = { + try { + out1.close() + } finally { + out2.close() + } + } +} + +class TeePrintOutputStream(out1: PrintStream, out2: PrintStream) extends PrintStream(out1) { + override def write(b: Int): Unit = synchronized { + out1.write(b) + out2.write(b) + } + + override def write(b: Array[Byte]): Unit = synchronized { + out1.write(b) + out2.write(b) + } + + override def write(b: Array[Byte], off: Int, len: Int): Unit = synchronized { + out1.write(b, off, len) + out2.write(b, off, len) + } + + override def flush(): Unit = { + out1.flush() + out2.flush() + } + + override def close(): Unit = { + try { + out1.close() + } finally { + out2.close() + } + } + + override def checkError(): Boolean = out1.checkError() || out2.checkError() + +} From 631c96872df9078064f4df5e42356bf1cd922f24 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 10:57:50 +0200 Subject: [PATCH 03/24] Use dedicated bsp log stream --- bsp/src/mill/bsp/BspWorker.scala | 1 - bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala | 2 +- main/api/src/mill/api/SystemStreams.scala | 2 +- runner/src/mill/runner/MillMain.scala | 10 +++++++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/bsp/src/mill/bsp/BspWorker.scala b/bsp/src/mill/bsp/BspWorker.scala index 1020cd65a6e..b219041ca9e 100644 --- a/bsp/src/mill/bsp/BspWorker.scala +++ b/bsp/src/mill/bsp/BspWorker.scala @@ -7,7 +7,6 @@ import mill.eval.Evaluator import mill.main.{BspServerHandle, BspServerResult} import mill.api.SystemStreams -import java.io.{InputStream, PrintStream} import java.net.URL import scala.concurrent.Promise import scala.util.{Failure, Success, Try} diff --git a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala index 7a6d6575f9a..26cfe381c60 100644 --- a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala +++ b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala @@ -76,7 +76,7 @@ class BspWorkerImpl() extends BspWorker { bspVersion = Constants.bspProtocolVersion, serverVersion = MillBuildInfo.millVersion, serverName = Constants.serverName, - logStream = streams.err, + logStream = streams.bspLog.getOrElse(streams.err), canReload = canReload ) with MillJvmBuildServer with MillJavaBuildServer with MillScalaBuildServer diff --git a/main/api/src/mill/api/SystemStreams.scala b/main/api/src/mill/api/SystemStreams.scala index a92366f1fd8..efb7c0cc8cc 100644 --- a/main/api/src/mill/api/SystemStreams.scala +++ b/main/api/src/mill/api/SystemStreams.scala @@ -2,4 +2,4 @@ package mill.api import java.io.{InputStream, PrintStream} -class SystemStreams(val out: PrintStream, val err: PrintStream, val in: InputStream) +class SystemStreams(val out: PrintStream, val err: PrintStream, val in: InputStream, val bspLog: Option[PrintStream] = None) diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index f1ea94b9bee..c89cbf4c045 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -30,7 +30,15 @@ object MillMain { System.setErr(errTee) errTee.println(msg) ( - new SystemStreams(initialSystemStreams.out, errTee, System.in), + new SystemStreams( + // out is used for the protocol + initialSystemStreams.out, + // err is default, but also tee-ed into the bsp log file + errTee, + System.in, + // the bsp log file for additional bsp server logging + Some(errFile) + ), Seq(errFile) ) } else { From dc2804e75f5edd6717d7a90297db29f18c8bbd71 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 11:35:53 +0200 Subject: [PATCH 04/24] Fix stale bsp worker resources --- bsp/src/mill/bsp/BSP.scala | 21 +++++++++++++++------ build.sc | 1 + main/src/mill/modules/Util.scala | 6 +++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 04499c84260..778ebe30109 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -23,12 +23,21 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { Agg(Dep.parse(BuildInfo.millBspWorkerDep)) } - private def bspWorkerLibs: T[Agg[PathRef]] = T { - mill.modules.Util.millProjectModule( - "MILL_BSP_WORKER", - "mill-bsp-worker", - repositoriesTask() - ) + private def bspWorkerLibs: T[Agg[PathRef]] = { + sys.props.getOrElse("MILL_UNDER_TEST", "0") match { + case "1" => T { + mill.modules.Util.millProjectModule( + "MILL_BSP_WORKER", + "mill-bsp-worker", + repositoriesTask() + ) + } + case _ => T { + resolveDeps(T.task { + bspWorkerIvyDeps().map(bindDependency()) + })() + } + } } /** diff --git a/build.sc b/build.sc index 9475182536b..7505821d0d0 100644 --- a/build.sc +++ b/build.sc @@ -1217,6 +1217,7 @@ trait IntegrationTestModule extends MillScalaModule { scalanativelib.testArgs() ++ runner.linenumbers.testArgs() ++ Seq( + s"-DMILL_UNDER_TEST=1", s"-DMILL_WORKSPACE_PATH=${workspaceDir().path}", s"-DMILL_TESTNG=${contrib.testng.runClasspath().map(_.path).mkString(",")}", s"-DMILL_VERSION=${millVersion()}", diff --git a/main/src/mill/modules/Util.scala b/main/src/mill/modules/Util.scala index 48223925c77..eff9bcf76c6 100644 --- a/main/src/mill/modules/Util.scala +++ b/main/src/mill/modules/Util.scala @@ -1,8 +1,8 @@ package mill.modules import coursier.Repository -import mill.BuildInfo -import mill.api.{Ctx, IO, Loose, PathRef} +import mill.{Agg, BuildInfo} +import mill.api.{Ctx, IO, Loose, PathRef, Result} object Util { @@ -70,7 +70,7 @@ object Util { resolveFilter: os.Path => Boolean = _ => true, // this should correspond to the mill runtime Scala version artifactSuffix: String = "_2.13" - ) = { + ): Result[Agg[PathRef]] = { millProperty(key) match { case Some(localPath) => mill.api.Result.Success( From 5a88b506ec853a8319d218d26e9eb20d7e0bba54 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 11:36:47 +0200 Subject: [PATCH 05/24] Tweak stream for BSP server --- bsp/src/mill/bsp/BSP.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 778ebe30109..32610449db2 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -94,11 +94,10 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { // This all goes to the BSP log file mill-bsp.stderr override def log: Logger = new Logger { override def colored: Boolean = false - override def systemStreams: SystemStreams = new SystemStreams( - streams.err, - streams.err, - DummyInputStream + out = streams.out, + err = streams.err, + in = DummyInputStream ) override def info(s: String): Unit = streams.err.println(s) override def error(s: String): Unit = streams.err.println(s) From 567731baf903384b9853a2953fe3e1c83c62b08b Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 11:43:23 +0200 Subject: [PATCH 06/24] Return the connection file --- bsp/src/mill/bsp/BSP.scala | 2 +- bsp/src/mill/bsp/BspWorker.scala | 2 +- bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 32610449db2..38a0ec9c155 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -54,7 +54,7 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { * reason, the message and stacktrace of the exception will be * printed to stdout. */ - def install(jobs: Int = 1): Command[Unit] = T.command { + def install(jobs: Int = 1): Command[(PathRef, String)] = T.command { // we create a file containing the additional jars to load val cpFile = T.workspace / Constants.bspDir / s"${Constants.serverName}.resources" os.write.over( diff --git a/bsp/src/mill/bsp/BspWorker.scala b/bsp/src/mill/bsp/BspWorker.scala index b219041ca9e..0d0e933a74c 100644 --- a/bsp/src/mill/bsp/BspWorker.scala +++ b/bsp/src/mill/bsp/BspWorker.scala @@ -17,7 +17,7 @@ trait BspWorker { def createBspConnection( jobs: Int, serverName: String - )(implicit ctx: Ctx): Unit + )(implicit ctx: Ctx): (PathRef, String) def startBspServer( initialEvaluator: Option[Evaluator], diff --git a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala index 26cfe381c60..f1f4edbfa7b 100644 --- a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala +++ b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala @@ -49,7 +49,7 @@ class BspWorkerImpl() extends BspWorker { override def createBspConnection( jobs: Int, serverName: String - )(implicit ctx: Ctx): Unit = { + )(implicit ctx: Ctx): (PathRef, String) = { // we create a json connection file val bspFile = ctx.workspace / Constants.bspDir / s"${serverName}.json" if (os.exists(bspFile)) ctx.log.info(s"Overwriting BSP connection file: ${bspFile}") @@ -58,7 +58,9 @@ class BspWorkerImpl() extends BspWorker { if (withDebug) ctx.log.debug( "Enabled debug logging for the BSP server. If you want to disable it, you need to re-run this install command without the --debug option." ) - os.write.over(bspFile, bspConnectionJson(jobs, withDebug), createFolders = true) + val connectionContent = bspConnectionJson(jobs, withDebug) + os.write.over(bspFile, connectionContent, createFolders = true) + (PathRef(bspFile), connectionContent) } override def startBspServer( From 085de8ecf62c54fcaa9645959c941cbf7ded61db Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 11:57:09 +0200 Subject: [PATCH 07/24] Use a versioned resource file for the BSP worker --- bsp/src/mill/bsp/BSP.scala | 2 +- bsp/src/mill/bsp/BspWorker.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 38a0ec9c155..e0db00a871c 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -56,7 +56,7 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { */ def install(jobs: Int = 1): Command[(PathRef, String)] = T.command { // we create a file containing the additional jars to load - val cpFile = T.workspace / Constants.bspDir / s"${Constants.serverName}.resources" + val cpFile = T.workspace / Constants.bspDir / s"${Constants.serverName}-${mill.BuildInfo.millVersion}.resources" os.write.over( cpFile, bspWorkerLibs().iterator.map(_.path.toNIO.toUri.toURL).mkString("\n"), diff --git a/bsp/src/mill/bsp/BspWorker.scala b/bsp/src/mill/bsp/BspWorker.scala index 0d0e933a74c..292f723c3ae 100644 --- a/bsp/src/mill/bsp/BspWorker.scala +++ b/bsp/src/mill/bsp/BspWorker.scala @@ -39,7 +39,7 @@ object BspWorker { case Some(x) => Result.Success(x) case None => // load extra classpath entries from file - val cpFile = millCtx.workspace / Constants.bspDir / s"${Constants.serverName}.resources" + val cpFile = millCtx.workspace / Constants.bspDir / s"${Constants.serverName}-${mill.BuildInfo.millVersion}.resources" if (!os.exists(cpFile)) return Result.Failure( "You need to run `mill mill.bsp.BSP/install` before you can use the BSP server" ) From 4b3acc1badb2d46835931005169ab1b5128d480c Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 12:59:00 +0200 Subject: [PATCH 08/24] Load initial BSP worker directly when installing it --- bsp/src/mill/bsp/BSP.scala | 5 ++-- bsp/src/mill/bsp/BspWorker.scala | 31 ++++++++++++++++------- main/src/mill/main/BspServerStarter.scala | 1 - 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index e0db00a871c..853c9bc87b9 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -56,13 +56,14 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { */ def install(jobs: Int = 1): Command[(PathRef, String)] = T.command { // we create a file containing the additional jars to load + val libUrls = bspWorkerLibs().map(_.path.toNIO.toUri.toURL).iterator.toSeq val cpFile = T.workspace / Constants.bspDir / s"${Constants.serverName}-${mill.BuildInfo.millVersion}.resources" os.write.over( cpFile, - bspWorkerLibs().iterator.map(_.path.toNIO.toUri.toURL).mkString("\n"), + libUrls.mkString("\n"), createFolders = true ) - BspWorker(T.ctx()).map(_.createBspConnection(jobs, Constants.serverName)) + BspWorker(T.ctx(), Some(libUrls)).map(_.createBspConnection(jobs, Constants.serverName)) } /** diff --git a/bsp/src/mill/bsp/BspWorker.scala b/bsp/src/mill/bsp/BspWorker.scala index 292f723c3ae..2d28c7c4501 100644 --- a/bsp/src/mill/bsp/BspWorker.scala +++ b/bsp/src/mill/bsp/BspWorker.scala @@ -34,23 +34,36 @@ object BspWorker { private[this] var worker: Option[BspWorker] = None - def apply(millCtx: Ctx.Workspace with Ctx.Home with Ctx.Log): Result[BspWorker] = { + def apply( + millCtx: Ctx.Workspace with Ctx.Home with Ctx.Log, + workerLibs: Option[Seq[URL]] = None + ): Result[BspWorker] = { worker match { case Some(x) => Result.Success(x) case None => - // load extra classpath entries from file - val cpFile = millCtx.workspace / Constants.bspDir / s"${Constants.serverName}-${mill.BuildInfo.millVersion}.resources" - if (!os.exists(cpFile)) return Result.Failure( - "You need to run `mill mill.bsp.BSP/install` before you can use the BSP server" - ) + val urls = workerLibs.map { urls => + millCtx.log.debug("Using direct submitted worker libs") + urls + }.getOrElse { + // load extra classpath entries from file + val cpFile = + millCtx.workspace / Constants.bspDir / s"${Constants.serverName}-${mill.BuildInfo.millVersion}.resources" + if (!os.exists(cpFile)) return Result.Failure( + "You need to run `mill mill.bsp.BSP/install` before you can use the BSP server" + ) - // TODO: if outdated, we could regenerate the resource file and re-load the worker + // TODO: if outdated, we could regenerate the resource file and re-load the worker - val urls = os.read(cpFile).linesIterator.map(u => new URL(u)).toSeq + // read the classpath from resource file + millCtx.log.debug(s"Reading worker classpath from file: ${cpFile}") + os.read(cpFile).linesIterator.map(u => new URL(u)).toSeq + } // create classloader with bsp.worker and deps val cl = mill.api.ClassLoader.create(urls, getClass().getClassLoader())(millCtx) - val workerVersion = Try { + + // check the worker version + Try { val workerBuildInfo = cl.loadClass(Constants.bspWorkerBuildInfoClass) workerBuildInfo.getMethod("millBspWorkerVersion").invoke(null) } match { diff --git a/main/src/mill/main/BspServerStarter.scala b/main/src/mill/main/BspServerStarter.scala index a783d27eb60..7c8b19ea365 100644 --- a/main/src/mill/main/BspServerStarter.scala +++ b/main/src/mill/main/BspServerStarter.scala @@ -3,7 +3,6 @@ package mill.main import mill.eval.Evaluator import mill.api.SystemStreams -import java.io.{InputStream, PrintStream} import scala.concurrent.Promise trait BspServerStarter { From a8078ed3b249b5618126c676923180358db565fd Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 12:59:17 +0200 Subject: [PATCH 09/24] Use a timeout when loading the BSP worker --- runner/src/mill/runner/BspContext.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runner/src/mill/runner/BspContext.scala b/runner/src/mill/runner/BspContext.scala index cf8fbbaf79b..de2b64e981f 100644 --- a/runner/src/mill/runner/BspContext.scala +++ b/runner/src/mill/runner/BspContext.scala @@ -4,7 +4,7 @@ import mill.api.internal import mill.main.{BspServerHandle, BspServerResult, BspServerStarter} import mill.api.SystemStreams -import java.util.concurrent.Executors +import java.util.concurrent.{Executors, TimeUnit} import scala.concurrent.duration.Duration import scala.concurrent.{Await, ExecutionContext, Future, Promise} import scala.util.chaining.scalaUtilChainingOps @@ -43,7 +43,7 @@ class BspContext(streams: SystemStreams, home: os.Path) { } }(serverThreadContext) - val handle = Await.result(bspServerHandle.future, Duration.Inf).tap { _ => + val handle = Await.result(bspServerHandle.future, Duration(10, TimeUnit.SECONDS)).tap { _ => streams.err.println("BSP server started") } From 1d3b97c3c9aa49ecad132c51b039097715719587 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 13:49:23 +0200 Subject: [PATCH 10/24] Return a ujson.Value instead of String --- bsp/src/mill/bsp/BSP.scala | 2 +- bsp/src/mill/bsp/BspWorker.scala | 2 +- bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 853c9bc87b9..55e23b69087 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -54,7 +54,7 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { * reason, the message and stacktrace of the exception will be * printed to stdout. */ - def install(jobs: Int = 1): Command[(PathRef, String)] = T.command { + def install(jobs: Int = 1): Command[(PathRef, ujson.Value)] = T.command { // we create a file containing the additional jars to load val libUrls = bspWorkerLibs().map(_.path.toNIO.toUri.toURL).iterator.toSeq val cpFile = T.workspace / Constants.bspDir / s"${Constants.serverName}-${mill.BuildInfo.millVersion}.resources" diff --git a/bsp/src/mill/bsp/BspWorker.scala b/bsp/src/mill/bsp/BspWorker.scala index 2d28c7c4501..40ac26e6d91 100644 --- a/bsp/src/mill/bsp/BspWorker.scala +++ b/bsp/src/mill/bsp/BspWorker.scala @@ -17,7 +17,7 @@ trait BspWorker { def createBspConnection( jobs: Int, serverName: String - )(implicit ctx: Ctx): (PathRef, String) + )(implicit ctx: Ctx): (PathRef, ujson.Value) def startBspServer( initialEvaluator: Option[Evaluator], diff --git a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala index f1f4edbfa7b..76dbc14934c 100644 --- a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala +++ b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala @@ -49,7 +49,7 @@ class BspWorkerImpl() extends BspWorker { override def createBspConnection( jobs: Int, serverName: String - )(implicit ctx: Ctx): (PathRef, String) = { + )(implicit ctx: Ctx): (PathRef, ujson.Value) = { // we create a json connection file val bspFile = ctx.workspace / Constants.bspDir / s"${serverName}.json" if (os.exists(bspFile)) ctx.log.info(s"Overwriting BSP connection file: ${bspFile}") @@ -60,7 +60,7 @@ class BspWorkerImpl() extends BspWorker { ) val connectionContent = bspConnectionJson(jobs, withDebug) os.write.over(bspFile, connectionContent, createFolders = true) - (PathRef(bspFile), connectionContent) + (PathRef(bspFile), upickle.default.read[ujson.Value](connectionContent)) } override def startBspServer( From 93fccf95e678729bcfcd8cfab326de0e0be227a4 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Wed, 5 Apr 2023 14:29:54 +0200 Subject: [PATCH 11/24] Formatted files --- bsp/src/mill/bsp/BSP.scala | 3 ++- main/api/src/mill/api/SystemStreams.scala | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 55e23b69087..d98d562179e 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -57,7 +57,8 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { def install(jobs: Int = 1): Command[(PathRef, ujson.Value)] = T.command { // we create a file containing the additional jars to load val libUrls = bspWorkerLibs().map(_.path.toNIO.toUri.toURL).iterator.toSeq - val cpFile = T.workspace / Constants.bspDir / s"${Constants.serverName}-${mill.BuildInfo.millVersion}.resources" + val cpFile = + T.workspace / Constants.bspDir / s"${Constants.serverName}-${mill.BuildInfo.millVersion}.resources" os.write.over( cpFile, libUrls.mkString("\n"), diff --git a/main/api/src/mill/api/SystemStreams.scala b/main/api/src/mill/api/SystemStreams.scala index efb7c0cc8cc..5e40ae4f616 100644 --- a/main/api/src/mill/api/SystemStreams.scala +++ b/main/api/src/mill/api/SystemStreams.scala @@ -2,4 +2,9 @@ package mill.api import java.io.{InputStream, PrintStream} -class SystemStreams(val out: PrintStream, val err: PrintStream, val in: InputStream, val bspLog: Option[PrintStream] = None) +class SystemStreams( + val out: PrintStream, + val err: PrintStream, + val in: InputStream, + val bspLog: Option[PrintStream] = None +) From 53d4def12981628939b40c8a3dc9fed2b2be47c5 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 09:20:17 +0200 Subject: [PATCH 12/24] Removed alternative worker dependency resolution --- bsp/src/mill/bsp/BSP.scala | 25 ++++++------------------- build.sc | 3 +-- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index d98d562179e..d3b191de14a 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -19,25 +19,12 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { private[this] val millServerHandle = Promise[BspServerHandle]() - private def bspWorkerIvyDeps: T[Agg[Dep]] = T { - Agg(Dep.parse(BuildInfo.millBspWorkerDep)) - } - - private def bspWorkerLibs: T[Agg[PathRef]] = { - sys.props.getOrElse("MILL_UNDER_TEST", "0") match { - case "1" => T { - mill.modules.Util.millProjectModule( - "MILL_BSP_WORKER", - "mill-bsp-worker", - repositoriesTask() - ) - } - case _ => T { - resolveDeps(T.task { - bspWorkerIvyDeps().map(bindDependency()) - })() - } - } + private def bspWorkerLibs: T[Agg[PathRef]] = T { + mill.modules.Util.millProjectModule( + "MILL_BSP_WORKER", + "mill-bsp-worker", + repositoriesTask() + ) } /** diff --git a/build.sc b/build.sc index 7505821d0d0..f43a5c83328 100644 --- a/build.sc +++ b/build.sc @@ -1097,8 +1097,7 @@ object bsp extends MillModule with BuildInfo{ def buildInfoMembers = T{ val workerDep = worker.publishSelfDependency() Seq( - BuildInfo.Value("bsp4jVersion", Deps.bsp4j.dep.version, "BSP4j version (BSP Protocol version)."), - BuildInfo.Value("millBspWorkerDep", s"${workerDep.group}:${workerDep.id}:${workerDep.version}", "BSP worker dependency.") + BuildInfo.Value("bsp4jVersion", Deps.bsp4j.dep.version, "BSP4j version (BSP Protocol version).") ) } From 443e78ddf22d99e3f661045abcb4eefe0441d392 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 09:33:17 +0200 Subject: [PATCH 13/24] Pass bsp logStream explicitly --- bsp/src/mill/bsp/BSP.scala | 2 ++ bsp/src/mill/bsp/BspWorker.scala | 2 ++ .../src/mill/bsp/worker/BspWorkerImpl.scala | 3 ++- main/api/src/mill/api/SystemStreams.scala | 3 +-- main/src/mill/main/BspServerStarter.scala | 2 ++ runner/src/mill/runner/BspContext.scala | 4 +++- runner/src/mill/runner/MillMain.scala | 20 +++++++++---------- runner/src/mill/runner/MillServerMain.scala | 9 +++++---- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index d3b191de14a..2683327bd0d 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -71,6 +71,7 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { override def startBspServer( initialEvaluator: Option[Evaluator], streams: SystemStreams, + logStream: Option[PrintStream], workspaceDir: os.Path, ammoniteHomeDir: os.Path, canReload: Boolean, @@ -103,6 +104,7 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { worker.startBspServer( initialEvaluator, streams, + logStream.getOrElse(streams.err), workspaceDir / Constants.bspDir, canReload, Seq(millServerHandle) ++ serverHandle.toSeq diff --git a/bsp/src/mill/bsp/BspWorker.scala b/bsp/src/mill/bsp/BspWorker.scala index 40ac26e6d91..181eb1967e9 100644 --- a/bsp/src/mill/bsp/BspWorker.scala +++ b/bsp/src/mill/bsp/BspWorker.scala @@ -7,6 +7,7 @@ import mill.eval.Evaluator import mill.main.{BspServerHandle, BspServerResult} import mill.api.SystemStreams +import java.io.PrintStream import java.net.URL import scala.concurrent.Promise import scala.util.{Failure, Success, Try} @@ -22,6 +23,7 @@ trait BspWorker { def startBspServer( initialEvaluator: Option[Evaluator], streams: SystemStreams, + logStream: PrintStream, logDir: os.Path, canReload: Boolean, serverHandles: Seq[Promise[BspServerHandle]] diff --git a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala index 76dbc14934c..42c73cef304 100644 --- a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala +++ b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala @@ -66,6 +66,7 @@ class BspWorkerImpl() extends BspWorker { override def startBspServer( initialEvaluator: Option[Evaluator], streams: SystemStreams, + logStream: PrintStream, logDir: os.Path, canReload: Boolean, serverHandles: Seq[Promise[BspServerHandle]] @@ -78,7 +79,7 @@ class BspWorkerImpl() extends BspWorker { bspVersion = Constants.bspProtocolVersion, serverVersion = MillBuildInfo.millVersion, serverName = Constants.serverName, - logStream = streams.bspLog.getOrElse(streams.err), + logStream = logStream, canReload = canReload ) with MillJvmBuildServer with MillJavaBuildServer with MillScalaBuildServer diff --git a/main/api/src/mill/api/SystemStreams.scala b/main/api/src/mill/api/SystemStreams.scala index 5e40ae4f616..1df7a7ffe94 100644 --- a/main/api/src/mill/api/SystemStreams.scala +++ b/main/api/src/mill/api/SystemStreams.scala @@ -5,6 +5,5 @@ import java.io.{InputStream, PrintStream} class SystemStreams( val out: PrintStream, val err: PrintStream, - val in: InputStream, - val bspLog: Option[PrintStream] = None + val in: InputStream ) diff --git a/main/src/mill/main/BspServerStarter.scala b/main/src/mill/main/BspServerStarter.scala index 7c8b19ea365..81449709cc5 100644 --- a/main/src/mill/main/BspServerStarter.scala +++ b/main/src/mill/main/BspServerStarter.scala @@ -3,12 +3,14 @@ package mill.main import mill.eval.Evaluator import mill.api.SystemStreams +import java.io.PrintStream import scala.concurrent.Promise trait BspServerStarter { def startBspServer( initialEvaluator: Option[Evaluator], streams: SystemStreams, + logStream: Option[PrintStream], workspaceDir: os.Path, ammoniteHomeDir: os.Path, canReload: Boolean, diff --git a/runner/src/mill/runner/BspContext.scala b/runner/src/mill/runner/BspContext.scala index de2b64e981f..e77eaedbd4d 100644 --- a/runner/src/mill/runner/BspContext.scala +++ b/runner/src/mill/runner/BspContext.scala @@ -4,6 +4,7 @@ import mill.api.internal import mill.main.{BspServerHandle, BspServerResult, BspServerStarter} import mill.api.SystemStreams +import java.io.PrintStream import java.util.concurrent.{Executors, TimeUnit} import scala.concurrent.duration.Duration import scala.concurrent.{Await, ExecutionContext, Future, Promise} @@ -11,7 +12,7 @@ import scala.util.chaining.scalaUtilChainingOps import scala.util.control.NonFatal @internal -class BspContext(streams: SystemStreams, home: os.Path) { +class BspContext(streams: SystemStreams, bspLogStream: Option[PrintStream], home: os.Path) { // BSP mode, run with a simple evaluator command to inject the evaluator // The command returns when the server exists or the workspace should be reloaded // if the `lastResult` is `ReloadWorkspace` we re-run the script in a loop @@ -30,6 +31,7 @@ class BspContext(streams: SystemStreams, home: os.Path) { BspServerStarter().startBspServer( initialEvaluator = None, streams = streams, + logStream = bspLogStream, workspaceDir = os.pwd, ammoniteHomeDir = home, canReload = true, diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index c89cbf4c045..ee369ecb384 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -16,7 +16,7 @@ object MillMain { def main(args: Array[String]): Unit = { val initialSystemStreams = new SystemStreams(System.out, System.err, System.in) // setup streams - val (runnerStreams, openStreams) = + val (runnerStreams, openStreams, bspLog) = if (args.headOption == Option("--bsp")) { // In BSP mode, we use System.in for protocol communication // and all Mill output (stdout and stderr) goes to a dedicated file @@ -35,15 +35,14 @@ object MillMain { initialSystemStreams.out, // err is default, but also tee-ed into the bsp log file errTee, - System.in, - // the bsp log file for additional bsp server logging - Some(errFile) + System.in ), - Seq(errFile) + Seq(errFile), + Some(errFile) ) } else { // Unchanged system stream - (initialSystemStreams, Seq()) + (initialSystemStreams, Seq(), None) } if (Properties.isWin && System.console() != null) @@ -55,12 +54,12 @@ object MillMain { RunnerState.empty, mill.util.Util.isInteractive(), runnerStreams, + bspLog, System.getenv().asScala.toMap, b => (), - userSpecifiedProperties0 = Map(), - initialSystemProperties = sys.props.toMap - ) - finally { + Map(), + sys.props.toMap + ) finally { openStreams.foreach(_.close()) } System.exit(if (result) 0 else 1) @@ -71,6 +70,7 @@ object MillMain { stateCache: RunnerState, mainInteractive: Boolean, streams0: SystemStreams, + bspLog: Option[PrintStream], env: Map[String, String], setIdle: Boolean => Unit, userSpecifiedProperties0: Map[String, String], diff --git a/runner/src/mill/runner/MillServerMain.scala b/runner/src/mill/runner/MillServerMain.scala index 2b455cc018c..8b52d0b4b51 100644 --- a/runner/src/mill/runner/MillServerMain.scala +++ b/runner/src/mill/runner/MillServerMain.scala @@ -66,11 +66,12 @@ object MillServerMain extends MillServerMain[RunnerState] { initialSystemProperties: Map[String, String] ): (Boolean, RunnerState) = { MillMain.main0( - args, - stateCache, + args = args, + stateCache = stateCache, mainInteractive = mainInteractive, - streams, - env, + streams = streams, + bspLog = None, + env = env, setIdle = setIdle, userSpecifiedProperties0 = userSpecifiedProperties, initialSystemProperties = initialSystemProperties From 619991cf445fb15f7e280bb68365224fda82c92a Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 10:17:07 +0200 Subject: [PATCH 14/24] Prepare merge --- runner/src/mill/runner/MillMain.scala | 24 ++++++++++++--------- runner/src/mill/runner/MillServerMain.scala | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index ee369ecb384..eb785dbe35f 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -50,16 +50,20 @@ object MillMain { val (result, _) = try main0( - args, - RunnerState.empty, - mill.util.Util.isInteractive(), - runnerStreams, - bspLog, - System.getenv().asScala.toMap, - b => (), - Map(), - sys.props.toMap - ) finally { + args = args, + stateCache = RunnerState.empty, + mainInteractive = mill.util.Util.isInteractive(), + streams0 = runnerStreams, + bspLog = bspLog, + env = System.getenv().asScala.toMap, + setIdle = b => (), + userSpecifiedProperties0 = Map(), + initialSystemProperties = sys.props.toMap + ) + finally { + System.setOut(initialSystemStreams.out) + System.setErr(initialSystemStreams.err) + System.setIn(initialSystemStreams.in) openStreams.foreach(_.close()) } System.exit(if (result) 0 else 1) diff --git a/runner/src/mill/runner/MillServerMain.scala b/runner/src/mill/runner/MillServerMain.scala index 8b52d0b4b51..383848d341c 100644 --- a/runner/src/mill/runner/MillServerMain.scala +++ b/runner/src/mill/runner/MillServerMain.scala @@ -69,7 +69,7 @@ object MillServerMain extends MillServerMain[RunnerState] { args = args, stateCache = stateCache, mainInteractive = mainInteractive, - streams = streams, + streams0 = streams, bspLog = None, env = env, setIdle = setIdle, From 680c142a0ff86ae9d304438c79294dce5971f376 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 11:17:56 +0200 Subject: [PATCH 15/24] rearrange code --- runner/src/mill/runner/MillMain.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index eb785dbe35f..0a1e2eefc86 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -22,13 +22,14 @@ object MillMain { // and all Mill output (stdout and stderr) goes to a dedicated file val stderrFile = os.pwd / ".bsp" / "mill-bsp.stderr" os.makeDir.all(stderrFile / os.up) - val msg = s"Mill in BSP mode, version ${BuildInfo.millVersion}, ${new java.util.Date()}" -// System.err.println(msg) val errFile = new PrintStream(new FileOutputStream(stderrFile.toIO, true)) val errTee = new TeePrintOutputStream(initialSystemStreams.err, errFile) System.setOut(errFile) System.setErr(errTee) + + val msg = s"Mill in BSP mode, version ${BuildInfo.millVersion}, ${new java.util.Date()}" errTee.println(msg) + ( new SystemStreams( // out is used for the protocol From 3122f2d2ef056ca745c4b241513a504fdab3bc2c Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 11:19:49 +0200 Subject: [PATCH 16/24] Cleanup --- runner/src/mill/runner/MillMain.scala | 2 +- ...tream.scala => TeePrintOutputStream.scala} | 32 +------------------ 2 files changed, 2 insertions(+), 32 deletions(-) rename runner/src/mill/runner/{TeeOutputStream.scala => TeePrintOutputStream.scala} (52%) diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index 0a1e2eefc86..d418a6b509d 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -29,7 +29,7 @@ object MillMain { val msg = s"Mill in BSP mode, version ${BuildInfo.millVersion}, ${new java.util.Date()}" errTee.println(msg) - + ( new SystemStreams( // out is used for the protocol diff --git a/runner/src/mill/runner/TeeOutputStream.scala b/runner/src/mill/runner/TeePrintOutputStream.scala similarity index 52% rename from runner/src/mill/runner/TeeOutputStream.scala rename to runner/src/mill/runner/TeePrintOutputStream.scala index 66c006c1ac8..24384ba7e58 100644 --- a/runner/src/mill/runner/TeeOutputStream.scala +++ b/runner/src/mill/runner/TeePrintOutputStream.scala @@ -1,36 +1,6 @@ package mill.runner -import java.io.{OutputStream, PrintStream} - -class TeeOutputStream(out1: OutputStream, out2: OutputStream) extends OutputStream { - override def write(b: Int): Unit = synchronized { - out1.write(b) - out2.write(b) - } - - override def write(b: Array[Byte]): Unit = synchronized { - out1.write(b) - out2.write(b) - } - - override def write(b: Array[Byte], off: Int, len: Int): Unit = synchronized { - out1.write(b, off, len) - out2.write(b, off, len) - } - - override def flush(): Unit = { - out1.flush() - out2.flush() - } - - override def close(): Unit = { - try { - out1.close() - } finally { - out2.close() - } - } -} +import java.io.PrintStream class TeePrintOutputStream(out1: PrintStream, out2: PrintStream) extends PrintStream(out1) { override def write(b: Int): Unit = synchronized { From c70202ee2c51d53dd504a766c89f211cc164008f Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 11:20:39 +0200 Subject: [PATCH 17/24] Renamed class --- runner/src/mill/runner/MillMain.scala | 2 +- .../runner/{TeePrintOutputStream.scala => TeePrintStream.scala} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename runner/src/mill/runner/{TeePrintOutputStream.scala => TeePrintStream.scala} (87%) diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index d418a6b509d..946a9309c03 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -23,7 +23,7 @@ object MillMain { val stderrFile = os.pwd / ".bsp" / "mill-bsp.stderr" os.makeDir.all(stderrFile / os.up) val errFile = new PrintStream(new FileOutputStream(stderrFile.toIO, true)) - val errTee = new TeePrintOutputStream(initialSystemStreams.err, errFile) + val errTee = new TeePrintStream(initialSystemStreams.err, errFile) System.setOut(errFile) System.setErr(errTee) diff --git a/runner/src/mill/runner/TeePrintOutputStream.scala b/runner/src/mill/runner/TeePrintStream.scala similarity index 87% rename from runner/src/mill/runner/TeePrintOutputStream.scala rename to runner/src/mill/runner/TeePrintStream.scala index 24384ba7e58..d54ec70c056 100644 --- a/runner/src/mill/runner/TeePrintOutputStream.scala +++ b/runner/src/mill/runner/TeePrintStream.scala @@ -2,7 +2,7 @@ package mill.runner import java.io.PrintStream -class TeePrintOutputStream(out1: PrintStream, out2: PrintStream) extends PrintStream(out1) { +class TeePrintStream(out1: PrintStream, out2: PrintStream) extends PrintStream(out1) { override def write(b: Int): Unit = synchronized { out1.write(b) out2.write(b) From 7495c7696ad0d3764742901ab4d473b33c108bfe Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 11:46:28 +0200 Subject: [PATCH 18/24] Added bspLog to context --- runner/src/mill/runner/MillMain.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index 946a9309c03..763b9d11376 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -194,7 +194,7 @@ object MillMain { } } - val bspContext = if (bspMode) Some(new BspContext(streams, config.home)) else None + val bspContext = if (bspMode) Some(new BspContext(streams, bspLog, config.home)) else None val targetsAndParams = bspContext.map(_.millArgs).getOrElse(config.leftoverArgs.value.toList) From 9e537226766981e2007f265d29010f3cc28c9e2e Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 13:01:48 +0200 Subject: [PATCH 19/24] Cleanup --- runner/src/mill/runner/MillMain.scala | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index 763b9d11376..13967e14d50 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -16,27 +16,23 @@ object MillMain { def main(args: Array[String]): Unit = { val initialSystemStreams = new SystemStreams(System.out, System.err, System.in) // setup streams - val (runnerStreams, openStreams, bspLog) = + val (runnerStreams, cleanupStreams, bspLog) = if (args.headOption == Option("--bsp")) { - // In BSP mode, we use System.in for protocol communication + // In BSP mode, we use System.in/out for protocol communication // and all Mill output (stdout and stderr) goes to a dedicated file val stderrFile = os.pwd / ".bsp" / "mill-bsp.stderr" os.makeDir.all(stderrFile / os.up) val errFile = new PrintStream(new FileOutputStream(stderrFile.toIO, true)) val errTee = new TeePrintStream(initialSystemStreams.err, errFile) - System.setOut(errFile) - System.setErr(errTee) - val msg = s"Mill in BSP mode, version ${BuildInfo.millVersion}, ${new java.util.Date()}" errTee.println(msg) - ( new SystemStreams( // out is used for the protocol - initialSystemStreams.out, + out = initialSystemStreams.out, // err is default, but also tee-ed into the bsp log file - errTee, - System.in + err = errTee, + in = System.in ), Seq(errFile), Some(errFile) @@ -62,10 +58,7 @@ object MillMain { initialSystemProperties = sys.props.toMap ) finally { - System.setOut(initialSystemStreams.out) - System.setErr(initialSystemStreams.err) - System.setIn(initialSystemStreams.in) - openStreams.foreach(_.close()) + cleanupStreams.foreach(_.close()) } System.exit(if (result) 0 else 1) } From 6e466ae5be571ac3c598d881cc19720ca1eec2fa Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 13:09:22 +0200 Subject: [PATCH 20/24] Refined BuildInfo implementation --- .../mill/contrib/buildinfo/BuildInfo.scala | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala b/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala index 2ea58e764c6..bee54d59f30 100644 --- a/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala +++ b/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala @@ -165,12 +165,17 @@ object BuildInfo { |package ${buildInfoPackageName} | |object $buildInfoObjectName { - | private val buildInfoProperties = new java.util.Properties - | - | private val buildInfoInputStream = getClass - | .getResourceAsStream("$buildInfoObjectName.buildinfo.properties") - | - | buildInfoProperties.load(buildInfoInputStream) + | private[this] val buildInfoProperties: java.util.Properties = { + | val props = new java.util.Properties + | val buildInfoInputStream = getClass + | .getResourceAsStream("${buildInfoObjectName}.buildinfo.properties") + | try { + | buildInfoProperties.load(buildInfoInputStream) + | } finally { + | buildInfoInputStream.close() + | } + | props + | } | | $bindingsCode |} @@ -180,21 +185,21 @@ object BuildInfo { |package ${buildInfoPackageName}; | |public class $buildInfoObjectName { - | private static java.util.Properties buildInfoProperties = new java.util.Properties(); + | private static final java.util.Properties buildInfoProperties = new java.util.Properties(); | | static { - | java.io.InputStream buildInfoInputStream = $buildInfoObjectName + | java.io.InputStream buildInfoInputStream = ${buildInfoObjectName} | .class - | .getResourceAsStream("$buildInfoObjectName.buildinfo.properties"); + | .getResourceAsStream("${buildInfoObjectName}.buildinfo.properties"); | - | try{ + | try { | buildInfoProperties.load(buildInfoInputStream); - | }catch(java.io.IOException e){ + | } catch (java.io.IOException e) { | throw new RuntimeException(e); - | }finally{ - | try{ + | } finally { + | try { | buildInfoInputStream.close(); - | }catch(java.io.IOException e){ + | } catch (java.io.IOException e) { | throw new RuntimeException(e); | } | } From 202aa529bd2356d4a195e826677f50b0f27cd66b Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 14:01:10 +0200 Subject: [PATCH 21/24] Fixed parser for changed dependency format of embedded build info --- bsp/src/mill/bsp/BSP.scala | 11 +++++++++-- scalalib/src/mill/scalalib/bsp/MillBuildModule.scala | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 2683327bd0d..f0a5f9eccae 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -77,7 +77,6 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { canReload: Boolean, serverHandle: Option[Promise[BspServerHandle]] = None ): BspServerResult = { - val ctx = new Ctx.Workspace with Ctx.Home with Ctx.Log { override def workspace: Path = workspaceDir override def home: Path = ammoniteHomeDir @@ -109,7 +108,15 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { canReload, Seq(millServerHandle) ++ serverHandle.toSeq ) - case _ => BspServerResult.Failure + case f: Result.Failure[_] => + streams.err.println("Failed to start the BSP worker. " + f.msg) + BspServerResult.Failure + case f : Result.Exception => + streams.err.println("Failed to start the BSP worker. " + f.throwable) + BspServerResult.Failure + case f => + streams.err.println("Failed to start the BSP worker. " + f) + BspServerResult.Failure } } diff --git a/scalalib/src/mill/scalalib/bsp/MillBuildModule.scala b/scalalib/src/mill/scalalib/bsp/MillBuildModule.scala index 2e5be145a2e..fa94f3720fe 100644 --- a/scalalib/src/mill/scalalib/bsp/MillBuildModule.scala +++ b/scalalib/src/mill/scalalib/bsp/MillBuildModule.scala @@ -38,7 +38,7 @@ trait MillBuildModule } override def compileIvyDeps: T[Agg[Dep]] = T { - val deps = Agg.from(BuildInfo.millEmbeddedDeps.map(d => ivy"${d}".forceVersion())) + val deps = Agg.from(BuildInfo.millEmbeddedDeps.split(",").map(d => ivy"${d}".forceVersion())) T.log.errorStream.println(s"compileIvyDeps: ${deps}") deps } From 0b32804388000fa9944645d60071caf5906c3d89 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 15:59:02 +0200 Subject: [PATCH 22/24] Fixed initialization logic --- .../src/mill/contrib/buildinfo/BuildInfo.scala | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala b/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala index bee54d59f30..3d10cb24894 100644 --- a/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala +++ b/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala @@ -165,16 +165,15 @@ object BuildInfo { |package ${buildInfoPackageName} | |object $buildInfoObjectName { - | private[this] val buildInfoProperties: java.util.Properties = { - | val props = new java.util.Properties - | val buildInfoInputStream = getClass + | private[this] val buildInfoProperties: java.util.Properties = new java.util.Properties() + | + | private[this] val buildInfoInputStream = getClass | .getResourceAsStream("${buildInfoObjectName}.buildinfo.properties") - | try { - | buildInfoProperties.load(buildInfoInputStream) - | } finally { - | buildInfoInputStream.close() - | } - | props + | + | try { + | buildInfoProperties.load(buildInfoInputStream) + | } finally { + | buildInfoInputStream.close() | } | | $bindingsCode From cd18ff72250eb9562445bf18e75329ad3c705109 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 16:04:17 +0200 Subject: [PATCH 23/24] Removed obsolete env var --- build.sc | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sc b/build.sc index f43a5c83328..b53117771c8 100644 --- a/build.sc +++ b/build.sc @@ -1216,7 +1216,6 @@ trait IntegrationTestModule extends MillScalaModule { scalanativelib.testArgs() ++ runner.linenumbers.testArgs() ++ Seq( - s"-DMILL_UNDER_TEST=1", s"-DMILL_WORKSPACE_PATH=${workspaceDir().path}", s"-DMILL_TESTNG=${contrib.testng.runClasspath().map(_.path).mkString(",")}", s"-DMILL_VERSION=${millVersion()}", From a1d57447aa814f59cdbf4dce5016699903e7dc20 Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Thu, 13 Apr 2023 16:31:27 +0200 Subject: [PATCH 24/24] scalafmt --- bsp/src/mill/bsp/BSP.scala | 2 +- runner/src/mill/runner/MillMain.scala | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index f0a5f9eccae..4a02f92abd1 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -111,7 +111,7 @@ object BSP extends ExternalModule with CoursierModule with BspServerStarter { case f: Result.Failure[_] => streams.err.println("Failed to start the BSP worker. " + f.msg) BspServerResult.Failure - case f : Result.Exception => + case f: Result.Exception => streams.err.println("Failed to start the BSP worker. " + f.throwable) BspServerResult.Failure case f => diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index 13967e14d50..bd1a3ce167f 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -187,7 +187,8 @@ object MillMain { } } - val bspContext = if (bspMode) Some(new BspContext(streams, bspLog, config.home)) else None + val bspContext = + if (bspMode) Some(new BspContext(streams, bspLog, config.home)) else None val targetsAndParams = bspContext.map(_.millArgs).getOrElse(config.leftoverArgs.value.toList)