diff options
Diffstat (limited to 'contrib')
4 files changed, 52 insertions, 32 deletions
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 |