diff options
author | Alexandra Dima <alexandra.dima@jetbrains.com> | 2019-06-25 17:29:51 +0200 |
---|---|---|
committer | Samvel Abrahamyan <samvel1024@gmail.com> | 2019-10-12 14:32:55 +0200 |
commit | 2319b109513ae7462d61fae69726546e3dc6eaf6 (patch) | |
tree | c360bfe20b174135260e3298ec4a1538af1188b9 /contrib/bsp/src | |
parent | 623f91a83c49564ffef49a2ad0f6b7e3c7b29105 (diff) | |
download | mill-2319b109513ae7462d61fae69726546e3dc6eaf6.tar.gz mill-2319b109513ae7462d61fae69726546e3dc6eaf6.tar.bz2 mill-2319b109513ae7462d61fae69726546e3dc6eaf6.zip |
Made install from MainMillBuildServer a mill command. Started simple implementation of buildTargetTest. Made sure targets are retrieved again everytime the workspaceBuildTargets request is sent
Diffstat (limited to 'contrib/bsp/src')
-rw-r--r-- | contrib/bsp/src/mill/contrib/MainMillBuildServer.scala | 25 | ||||
-rw-r--r-- | contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala | 154 |
2 files changed, 127 insertions, 52 deletions
diff --git a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala index 56ee1419..8905a622 100644 --- a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala +++ b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala @@ -10,7 +10,7 @@ import upickle.default._ import ch.epfl.scala.bsp4j.{BspConnectionDetails, BuildClient} import mill._ import mill.contrib.bsp.ModuleUtils -import mill.define.{Discover, ExternalModule, Target, Task} +import mill.define.{Command, Discover, ExternalModule, Target, Task} import mill.eval.Evaluator import mill.scalalib._ import mill.util.DummyLogger @@ -74,17 +74,18 @@ object MainMillBuildServer extends ExternalModule { * printed to stdout. * */ - def installMillBsp(): Unit = { - val bspDirecotry = os.pwd / ".bsp" + def install(ev: Evaluator): Command[Unit] = T.command{ + val bspDirectory = os.pwd / ".bsp" try { - os.makeDir(bspDirecotry) - os.write(bspDirecotry / "mill-bsp.json", Json.stringify(createBspConnectionJson())) + os.makeDir(bspDirectory) + os.write(bspDirectory / "mill-bsp.json", Json.stringify(createBspConnectionJson())) } catch { case e: FileAlreadyExistsException => { println("The bsp connection json file probably exists already - will be overwritten") - os.remove.all(bspDirecotry) - installMillBsp() + os.remove.all(bspDirectory) + install(ev) + () } //TODO: Do I want to catch this or throw the exception? case e: Exception => println("An exception occurred while installing mill-bsp: " + e.getMessage + @@ -117,9 +118,9 @@ object MainMillBuildServer extends ExternalModule { * @return: mill.Command which executes the starting of the * server */ - def startServer(ev: Evaluator) = T.command { + def startServer(ev: Evaluator): Command[Unit] = T.command { - val millServer = new mill.contrib.bsp.MillBuildServer(modules(ev)(), ev, bspVersion, version, languages) + val millServer = new mill.contrib.bsp.MillBuildServer(ev, bspVersion, version, languages) val executor = Executors.newCachedThreadPool() val stdin = System.in @@ -147,8 +148,8 @@ object MainMillBuildServer extends ExternalModule { } } - def experiment(ev: Evaluator) = T.command { - val millServer = new mill.contrib.bsp.MillBuildServer(modules(ev)(), ev, bspVersion, version, languages) + def experiment(ev: Evaluator): Command[Unit] = T.command { + val millServer = new mill.contrib.bsp.MillBuildServer(ev, bspVersion, version, languages) val mods: Seq[JavaModule] = modules(ev)() for (module <- mods) { System.err.println("Module: " + module + "has capabilities: " + ModuleUtils.getModuleCapabilities(module, ev)) @@ -167,8 +168,6 @@ object MainMillBuildServer extends ExternalModule { */ def main(args: Array[String]) { args(0) match { - //case "exp" => experiment - case "install" => installMillBsp() //TODO: Do I want to make this a mill command instead? case e: String => println("Wrong command, you can only use:\n " + "install - creates the bsp connection json file\n") } diff --git a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala index bc8efc3e..9865a5a2 100644 --- a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala +++ b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala @@ -19,8 +19,7 @@ import mill.util.{PrintLogger, Ctx} import mill.define.{Discover, ExternalModule, Target, Task} -class MillBuildServer(modules: Seq[JavaModule], - evaluator: Evaluator, +class MillBuildServer(evaluator: Evaluator, _bspVersion: String, serverVersion:String, languages: List[String]) extends ExternalModule with BuildServer with ScalaBuildServer { @@ -32,15 +31,15 @@ class MillBuildServer(modules: Seq[JavaModule], val supportedLanguages: List[String] = languages val millServerVersion: String = serverVersion var cancelator: () => Unit = () => () - - var millModules: Seq[JavaModule] = modules + var millEvaluator: Evaluator = evaluator + var millModules: Seq[JavaModule] = getMillModules(millEvaluator) var client: BuildClient = _ var moduleToTargetId: Predef.Map[JavaModule, BuildTargetIdentifier] = ModuleUtils.getModuleTargetIdMap(millModules) var targetIdToModule: Predef.Map[BuildTargetIdentifier, JavaModule] = targetToModule(moduleToTargetId) var moduleToTarget: Predef.Map[JavaModule, BuildTarget] = ModuleUtils.millModulesToBspTargets(millModules, evaluator, List("scala", "java")) - var millEvaluator: Evaluator = evaluator + var clientInitialized = false val ctx: Ctx.Log with Ctx.Home = new Ctx.Log with Ctx.Home { @@ -85,6 +84,7 @@ class MillBuildServer(modules: Seq[JavaModule], } override def workspaceBuildTargets(): CompletableFuture[WorkspaceBuildTargetsResult] = { + recomputeTargets() val future = new CompletableFuture[WorkspaceBuildTargetsResult]() val result = new WorkspaceBuildTargetsResult(moduleToTarget.values.toList.asJava) future.complete(result) @@ -247,7 +247,7 @@ class MillBuildServer(modules: Seq[JavaModule], taskFinishParams.setDataKind("compile-report") val compileReport = new CompileReport(targetId, numFailures, 0) compileReport.setOriginId(compileParams.getOriginId) - compileReport.setTime(compileTime) + compileReport.setTime(compileTime.toLong) taskFinishParams.setData(compileReport) client.onBuildTaskFinish(taskFinishParams) } @@ -287,7 +287,101 @@ class MillBuildServer(modules: Seq[JavaModule], future } - override def buildTargetTest(testParams: TestParams): CompletableFuture[TestResult] = ??? + private[this] def getTestReport(targetId: BuildTargetIdentifier, results: Seq[TestRunner.Result]): TestReport = { + val testReport = new TestReport(targetId, 0, 0, 0, 0, 0) + testReport.setTime(results.map(r => r.duration).sum) + for (result <- results) { + result.status match { + case "Passed" => testReport.setPassed(testReport.getPassed + 1) + case "Failed" => testReport.setFailed(testReport.getFailed + 1) + case "Ignored" => testReport.setIgnored(testReport.getIgnored + 1) + case "Cancelled" => testReport.setCancelled(testReport.getCancelled + 1) + case "Skipped" => testReport.setSkipped(testReport.getSkipped + 1) + } + } + testReport + } + + private[this] def getStatusCode(results: Seq[TestRunner.Result]): StatusCode = { + if ( results.exists(res => res.status == "Failed") ) { + StatusCode.ERROR + } else if ( results.exists(res => res.status == "Cancelled") ) { + StatusCode.CANCELLED + }else { + StatusCode.OK + } + } + + override def buildTargetTest(testParams: TestParams): CompletableFuture[TestResult] = { + def getTestResult (implicit ctx: Ctx.Log with Ctx.Home ): TestResult = { + + val argsMap = testParams.getData match { + case scalaTestParams: ScalaTestParams => + (for (testItem <- scalaTestParams.getTestClasses.asScala) + yield (testItem.getTarget, testItem.getClasses.asScala.toSeq)).toMap + + case default => (for (targetId <- testParams.getTargets.asScala) yield (targetId, Seq.empty[String])).toMap + } + var overallStatusCode = StatusCode.OK + for (targetId <- testParams.getTargets.asScala) { + val module = targetIdToModule(targetId) + module match { + case m: TestModule => val testModule = m.asInstanceOf[TestModule] + val testTask = testModule.test(argsMap(targetId).mkString(" ")) + val passed = 0; + val ignored = 0; + val skipped = 0; + val failed = 0; + val cancelled = 0 + // send notification to client that testing of this target started + val taskStartParams = new TaskStartParams(new TaskId(testTask.hashCode().toString)) + taskStartParams.setEventTime(System.currentTimeMillis()) + taskStartParams.setMessage("Testing target: " + targetId) + taskStartParams.setDataKind("test-task") + taskStartParams.setData(new TestTask(targetId)) + client.onBuildTaskStart(taskStartParams) + + val (msg, results) = TestRunner.runTests( + TestRunner.frameworks(evaluateInformativeTask(millEvaluator, testModule.testFrameworks).left.get), + evaluateInformativeTask(millEvaluator, testModule.runClasspath).left.get.map(_.path), + Agg(evaluateInformativeTask(millEvaluator, testModule.compile).left.get.classes.path), + argsMap(targetId) + ) + + val endTime = System.currentTimeMillis() + // send notification to client that testing of this target ended => test report + val statusCode = getStatusCode(results) + val taskFinishParams = new TaskFinishParams( + new TaskId(testTask.hashCode().toString), + getStatusCode(results) + ) + taskFinishParams.setEventTime(endTime) + taskFinishParams.setMessage("Finished testing target: " + + moduleToTarget(targetIdToModule(targetId)).getDisplayName) + taskFinishParams.setDataKind("test-report") + taskFinishParams.setData(getTestReport(targetId, results)) + client.onBuildTaskFinish(taskFinishParams) + + statusCode match { + case StatusCode.ERROR => overallStatusCode = StatusCode.ERROR + case default => + } + case default => + } + } + val testResult = new TestResult(overallStatusCode) + testParams.getOriginId match { + case id: String => + //TODO: Add the messages from mill to the data field? + testResult.setOriginId(id) + testResult + case default => testResult + } + } + val future = new CompletableFuture[TestResult]() + future.complete(getTestResult(ctx)) + future + } override def buildTargetCleanCache(cleanCacheParams: CleanCacheParams): CompletableFuture[CleanCacheResult] = ??? @@ -318,40 +412,8 @@ class MillBuildServer(modules: Seq[JavaModule], future } -// private[this] def getSpecifiedMainClass(module: JavaModule): Either[Any, String] = { -// val mainClass = evaluateInformativeTask(module.finalMainClassOpt).left.get -// mainClass match { -// case main: Left[String, String] => Left(AnyRef) -// case main: Right[String, String] => Right(main.value) -// } -// } - override def buildTargetScalaMainClasses(scalaMainClassesParams: ScalaMainClassesParams): CompletableFuture[ScalaMainClassesResult] = { -// def getScalaMainClasses: ScalaMainClassesResult = { -// var items = List.empty[ScalaMainClassesItem] -// for (targetId <- scalaMainClassesParams.getTargets.asScala) { -// val module = targetIdToModule(targetId) -// var mainClasses = List.empty[ScalaMainClass] -// -// val specifiedMainClass = getSpecifiedMainClass(module) -// specifiedMainClass match { -// case main: Left[Any, String] => {} -// case main: Right[Any, String] => mainClasses ++= List(new ScalaMainClass(specifiedMainClass.getOrElse(""), -// evaluateInformativeTask(module.forkArgs).left.get.toList.asJava, -// List.empty[String].asJava)) -// } -// -// -// for (mainClass <- evaluateInformativeTask(module.zincWorker.worker).left.get. -// discoverMainClasses(evaluateInformativeTask(module.compile).left.get). -// filter(main => !main.equals(specifiedMainClass))) { -// mainClasses ++= List(new ScalaMainClass(mainClass, List.empty[String].asJava, List.empty[String].asJava)) -// } -// items ++= List(new ScalaMainClassesItem(targetId, mainClasses.asJava)) -// } -// new ScalaMainClassesResult(items.asJava) -// } def getScalaMainClasses: ScalaMainClassesResult = { var items = List.empty[ScalaMainClassesItem] @@ -411,4 +473,18 @@ class MillBuildServer(modules: Seq[JavaModule], moduleToTargetId.keys.map(mod => (moduleToTargetId(mod), mod)).toMap } + + private[this] def getMillModules(ev: Evaluator): Seq[JavaModule] = { + ev.rootModule.millInternal.segmentsToModules.values. + collect { + case m: scalalib.JavaModule => m + }.toSeq + } + + private[this] def recomputeTargets(): Unit = { + millModules = getMillModules(millEvaluator) + moduleToTargetId = ModuleUtils.getModuleTargetIdMap(millModules) + targetIdToModule = targetToModule(moduleToTargetId) + moduleToTarget = ModuleUtils.millModulesToBspTargets(millModules, evaluator, List("scala", "java")) + } } |