summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandra Dima <alexandra.dima@jetbrains.com>2019-07-25 17:32:21 +0200
committerSamvel Abrahamyan <samvel1024@gmail.com>2019-10-12 14:33:11 +0200
commitc02b1bf61ea714b76b8c53759301bfb5be535fc9 (patch)
treea2caad1b2b4c609cab683a8696c490a632b43720
parent8138acf4911b668b3b15c19fd51c4f5e6aadc083 (diff)
downloadmill-c02b1bf61ea714b76b8c53759301bfb5be535fc9.tar.gz
mill-c02b1bf61ea714b76b8c53759301bfb5be535fc9.tar.bz2
mill-c02b1bf61ea714b76b8c53759301bfb5be535fc9.zip
Changed the clean cache method back to a subprocess because this way it can wait for the output directories to actually be removed. Use IO instead of NIO for converting os.Path to URIs. Don't display the stack trace in the start method in case of CancelationException, which just means the server stopped. Also added support for tracing bsp messages inside a bsp.log file in the working directory of the project being built.
-rw-r--r--.gitignore3
-rw-r--r--contrib/bsp/src/mill/contrib/MainMillBuildServer.scala9
-rw-r--r--contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala2
-rw-r--r--contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala59
-rw-r--r--contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala14
5 files changed, 54 insertions, 33 deletions
diff --git a/.gitignore b/.gitignore
index 84df7fe8..af52d378 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,4 +10,5 @@ out/
contrib/bsp/mill-external-bs
contrib/bsp/mill-out-bs
mill.iml
-.bsp/ \ No newline at end of file
+.bsp/
+bsp.log \ No newline at end of file
diff --git a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala
index aa4cf211..d31eb7f4 100644
--- a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala
+++ b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala
@@ -1,15 +1,20 @@
package mill.contrib
+import java.io.{File, PrintWriter}
+
import play.api.libs.json._
import java.nio.file.FileAlreadyExistsException
import java.util.concurrent.Executors
+
import upickle.default._
import ch.epfl.scala.bsp4j._
import mill._
import mill.define.{Command, Discover, ExternalModule}
import mill.eval.Evaluator
import org.eclipse.lsp4j.jsonrpc.Launcher
+
import scala.collection.JavaConverters._
+import scala.concurrent.CancellationException
object BSP extends ExternalModule {
@@ -103,7 +108,8 @@ object BSP extends ExternalModule {
.setOutput(stdout)
.setInput(stdin)
.setLocalService(millServer)
- .setRemoteInterface(classOf[BuildClient])
+ .setRemoteInterface(classOf[BuildClient]).
+ traceMessages(new PrintWriter((os.pwd/ "bsp.log" ).toIO))
.setExecutorService(executor)
.create()
millServer.onConnectWithClient(launcher.getRemoteProxy)
@@ -111,6 +117,7 @@ object BSP extends ExternalModule {
millServer.cancelator = () => listening.cancel(true)
val voidFuture = listening.get()
} catch {
+ case _: CancellationException => System.err.println("The mill server was shut down.")
case e: Exception =>
System.err.println("An exception occured while connecting to the client.")
System.err.println("Cause: " + e.getCause)
diff --git a/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala b/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala
index a90b02a5..ba42a67a 100644
--- a/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala
+++ b/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala
@@ -89,7 +89,7 @@ class BspLoggedReporter(client: bsp.BuildClient,
val textDocument = new TextDocumentIdentifier(
sourceFile.getOrElse(None) match {
case None => targetId.getUri
- case f: File => f.toPath.toUri.toString
+ case f: File => f.toURI.toString
})
val params = new bsp.PublishDiagnosticsParams(textDocument,
targetId,
diff --git a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala
index 77e3ff38..247f5ddb 100644
--- a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala
+++ b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala
@@ -2,6 +2,7 @@ package mill.contrib.bsp
import sbt.testing._
import java.util.concurrent.CompletableFuture
+
import mill.scalalib.Lib.discoverTests
import ch.epfl.scala.bsp4j._
import mill.{scalalib, _}
@@ -11,6 +12,7 @@ import mill.eval.Evaluator
import mill.scalalib._
import mill.scalalib.api.CompilationResult
import sbt.internal.inc._
+
import scala.collection.JavaConverters._
import mill.modules.Jvm
import mill.util.Ctx
@@ -19,6 +21,8 @@ import mill.main.MainModule
import sbt.internal.util.{ConsoleOut, MainAppender, ManagedLogger}
import sbt.util.LogExchange
+import scala.io.Source
+
class MillBuildServer(evaluator: Evaluator,
_bspVersion: String,
@@ -108,12 +112,12 @@ class MillBuildServer(evaluator: Evaluator,
for (source <- sources) {
itemSources ++= List(
- new SourceItem(source.toNIO.toAbsolutePath.toUri.toString, SourceItemKind.DIRECTORY, false))
+ new SourceItem(source.toIO.toURI.toString, SourceItemKind.DIRECTORY, false))
}
for (genSource <- generatedSources) {
itemSources ++= List(
- new SourceItem(genSource.toNIO.toAbsolutePath.toUri.toString, SourceItemKind.DIRECTORY, true))
+ new SourceItem(genSource.toIO.toURI.toString, SourceItemKind.DIRECTORY, true))
}
items ++= List(new SourcesItem(targetId, itemSources.asJava))
@@ -162,7 +166,7 @@ class MillBuildServer(evaluator: Evaluator,
case m: JavaModule => sources ++= List()
}
items ++= List(new DependencySourcesItem(targetId, sources.
- map(pathRef => pathRef.path.toNIO.toAbsolutePath.toUri.toString).
+ map(pathRef => pathRef.path.toIO.toURI.toString).
toList.asJava))
}
@@ -180,7 +184,7 @@ class MillBuildServer(evaluator: Evaluator,
val millModule = targetIdToModule(targetId)
val resources = evaluateInformativeTask(evaluator, millModule.resources, Agg.empty[PathRef]).
flatMap(pathRef => os.walk(pathRef.path)).
- map(path => path.toNIO.toAbsolutePath.toUri.toString).
+ map(path => path.toIO.toURI.toString).
toList.asJava
items ++= List(new ResourcesItem(targetId, resources))
}
@@ -355,26 +359,32 @@ class MillBuildServer(evaluator: Evaluator,
}
override def buildTargetCleanCache(cleanCacheParams: CleanCacheParams): CompletableFuture[CleanCacheResult] = {
- def getCleanCacheResult: CleanCacheResult = {
- var msg = ""
- var cleaned = true
- for (targetId <- cleanCacheParams.getTargets.asScala) {
- val module = targetIdToModule(targetId)
- val mainModule = new MainModule {
- override implicit def millDiscover: Discover[_] = {
- Discover[this.type]
+
+ def getCleanCacheResult: CleanCacheResult = {
+ var msg = ""
+ var cleaned = true
+ for (targetId <- cleanCacheParams.getTargets.asScala) {
+ val module = targetIdToModule(targetId)
+ val cleanCommand = Array("java",
+ s"-DMILL_CLASSPATH=${System.getProperty("MILL_CLASSPATH")}",
+ s"-DMILL_VERSION=${System.getProperty("MILL_VERSION")}",
+ "-Djna.nosys=true", "-cp",
+ System.getProperty("MILL_CLASSPATH"),
+ "mill.MillMain", "clean",
+ s"${module.millModuleSegments.render}.compile")
+ val process = Runtime.getRuntime.exec(cleanCommand, null, os.pwd.toIO)
+
+ val processIn = process.getInputStream
+ val processErr = process.getErrorStream
+
+ val errMessage = Source.fromInputStream(processErr).getLines().mkString("\n")
+ val message = Source.fromInputStream(processIn).getLines().mkString("\n")
+ msg += s"Cleaning cache for target ${targetId} produced the following message: ${message}, ${errMessage}"
+ if (msg.contains("failed") || msg.contains("Error")) {
+ cleaned = false
}
+ process.waitFor()
}
- val cleanCommand = mainModule.clean(millEvaluator, List(s"${module.millModuleSegments.render}.compile"):_*)
- val cleanResult = millEvaluator.evaluate(
- Strict.Agg(cleanCommand),
- logger = new MillBspLogger(client, cleanCommand.hashCode, millEvaluator.log)
- )
- if (cleanResult.failing.keyCount > 0) {
- cleaned = false
- msg += s" Target ${module.millModuleSegments.render} could not be cleaned."
- }
- }
new CleanCacheResult(msg, cleaned)
}
handleExceptions[String, CleanCacheResult]((in) => getCleanCacheResult, "")
@@ -390,7 +400,7 @@ class MillBuildServer(evaluator: Evaluator,
case m: ScalaModule =>
val options = evaluateInformativeTask(evaluator, m.scalacOptions, Seq.empty[String]).toList
val classpath = evaluateInformativeTask(evaluator, m.compileClasspath, Agg.empty[PathRef]).
- map(pathRef => pathRef.path.toNIO.toAbsolutePath.toUri.toString).toList
+ map(pathRef => pathRef.path.toIO.toURI.toString).toList
val classDirectory = (Evaluator.resolveDestPaths(os.pwd / "out" , m.millModuleSegments).
dest / "classes").toIO.toURI.toString
@@ -403,6 +413,9 @@ class MillBuildServer(evaluator: Evaluator,
handleExceptions[String, ScalacOptionsResult]((in) => getScalacOptionsResult, "")
}
+ //TODO: In the case when mill fails to provide a main classes because multiple were
+ // defined for the same module, do something so that those can still be detected
+ // such that IntelliJ can run any of them
override def buildTargetScalaMainClasses(scalaMainClassesParams: ScalaMainClassesParams):
CompletableFuture[ScalaMainClassesResult] = {
diff --git a/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala b/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala
index 85a808a8..ffe3f8d7 100644
--- a/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala
+++ b/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala
@@ -120,7 +120,7 @@ object ModuleUtils {
List.empty[String].asJava,
List.empty[BuildTargetIdentifier].asJava,
new BuildTargetCapabilities(false, false, false))
- rootTarget.setBaseDirectory(rootModule.millSourcePath.toNIO.toAbsolutePath.toUri.toString)
+ rootTarget.setBaseDirectory(rootModule.millSourcePath.toIO.toURI.toString)
rootTarget.setDataKind("scala")
rootTarget.setTags(List(BuildTargetTag.LIBRARY, BuildTargetTag.APPLICATION).asJava)
rootTarget.setData(computeBuildTargetData(rootModule, evaluator))
@@ -169,7 +169,7 @@ object ModuleUtils {
}
buildTarget.setData(dataBuildTarget)
buildTarget.setDisplayName(moduleName(module.millModuleSegments))
- buildTarget.setBaseDirectory(module.intellijModulePath.toNIO.toAbsolutePath.toUri.toString)
+ buildTarget.setBaseDirectory(module.intellijModulePath.toIO.toURI.toString)
buildTarget
}
@@ -195,7 +195,7 @@ object ModuleUtils {
Util.scalaBinaryVersion(scalaVersion),
getScalaTargetPlatform(m),
computeScalaLangDependencies(m, evaluator).
- map(pathRef => pathRef.path.toNIO.toAbsolutePath.toUri.toString).
+ map(pathRef => pathRef.path.toIO.toURI.toString).
toList.asJava)
case m: JavaModule =>
@@ -242,9 +242,9 @@ object ModuleUtils {
evaluateInformativeTask(evaluator, module.resolveDeps(module.scalaLibraryIvyDeps), Loose.Agg.empty[PathRef]) ++
evaluateInformativeTask(evaluator, module.scalacPluginClasspath, Loose.Agg.empty[PathRef]) ++
evaluateInformativeTask(evaluator, module.resolveDeps(module.ivyDeps), Loose.Agg.empty[PathRef]).
- filter(pathRef => pathRef.path.toNIO.toAbsolutePath.toUri.toString.contains("scala-compiler") ||
- pathRef.path.toNIO.toAbsolutePath.toUri.toString.contains("scala-reflect") ||
- pathRef.path.toNIO.toAbsolutePath.toUri.toString.contains("scala-library"))
+ filter(pathRef => pathRef.path.toIO.toURI.toString.contains("scala-compiler") ||
+ pathRef.path.toIO.toURI.toString.contains("scala-reflect") ||
+ pathRef.path.toIO.toURI.toString.contains("scala-library"))
}
// Obtain the scala platform for `module`
@@ -268,7 +268,7 @@ object ModuleUtils {
(for ( module <- modules )
yield (module, new BuildTargetIdentifier(
(module.millOuterCtx.millSourcePath / os.RelPath(moduleName(module.millModuleSegments))).
- toNIO.toAbsolutePath.toUri.toString))).toMap
+ toIO.toURI.toString))).toMap
}
// this is taken from mill.scalalib GenIdeaImpl