From a0e3d8985540f8aa45b03b9aa092e8b776dd536c Mon Sep 17 00:00:00 2001 From: Samuel CLARENC Date: Thu, 17 Jun 2021 11:09:08 +0200 Subject: [PATCH] Implement BSP buildTarget/resources command --- main/src/main/scala/sbt/Keys.scala | 2 ++ .../internal/server/BuildServerProtocol.scala | 31 +++++++++++++++++++ .../test/scala/testpkg/BuildServerTest.scala | 13 ++++++++ 3 files changed, 46 insertions(+) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index bd2075346..33f4d628d 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -405,6 +405,8 @@ object Keys { val bspBuildTarget = taskKey[BuildTarget]("Description of the BSP build targets").withRank(DTask) val bspBuildTargetSources = inputKey[Unit]("").withRank(DTask) val bspBuildTargetSourcesItem = taskKey[SourcesItem]("").withRank(DTask) + val bspBuildTargetResources = inputKey[Unit]("").withRank(DTask) + val bspBuildTargetResourcesItem = taskKey[ResourcesItem]("").withRank(DTask) val bspBuildTargetDependencySources = inputKey[Unit]("").withRank(DTask) val bspBuildTargetDependencySourcesItem = taskKey[DependencySourcesItem]("").withRank(DTask) val bspBuildTargetCompile = inputKey[Unit]("").withRank(DTask) diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index 9a4acba8d..dd3b68bf9 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -117,6 +117,19 @@ object BuildServerProtocol { } }.evaluated, bspBuildTargetSources / aggregate := false, + bspBuildTargetResources := Def.inputTaskDyn { + val s = state.value + val workspace = bspWorkspace.value + val targets = spaceDelimited().parsed.map(uri => BuildTargetIdentifier(URI.create(uri))) + val filter = ScopeFilter.in(targets.map(workspace)) + // run the worker task concurrently + Def.task { + val items = bspBuildTargetResourcesItem.all(filter).value + val result = ResourcesResult(items.toVector) + s.respondEvent(result) + } + }.evaluated, + bspBuildTargetResources / aggregate := false, bspBuildTargetDependencySources := Def.inputTaskDyn { val s = state.value val workspace = bspWorkspace.value @@ -201,6 +214,18 @@ object BuildServerProtocol { }) SourcesItem(id, items) }, + bspBuildTargetResourcesItem := { + val id = bspTargetIdentifier.value + // Trigger resource generation + val _ = managedResources.value + val uris = resourceDirectories.value.toVector + .map { resourceDirectory => + // Add any missing ending slash to the URI to explicitly mark it as a directory + // See https://github.com/build-server-protocol/build-server-protocol/issues/181 for more information + URI.create(s"${resourceDirectory.toURI.toString.replaceAll("([^/])$", "$1/")}") + } + ResourcesItem(id, uris) + }, bspBuildTargetDependencySourcesItem := dependencySourcesItemTask.value, bspBuildTargetCompileItem := bspCompileTask.value, bspBuildTargetRun := bspRunTask.evaluated, @@ -319,6 +344,12 @@ object BuildServerProtocol { val targets = param.targets.map(_.uri).mkString(" ") val command = Keys.bspScalaMainClasses.key val _ = callback.appendExec(s"$command $targets", Some(r.id)) + + case r if r.method == "buildTarget/resources" => + val param = Converter.fromJson[ResourcesParams](json(r)).get + val targets = param.targets.map(_.uri).mkString(" ") + val command = Keys.bspBuildTargetResources.key + val _ = callback.appendExec(s"$command $targets", Some(r.id)) }, onResponse = PartialFunction.empty, onNotification = { diff --git a/server-test/src/test/scala/testpkg/BuildServerTest.scala b/server-test/src/test/scala/testpkg/BuildServerTest.scala index e4c42c4fd..48c26658a 100644 --- a/server-test/src/test/scala/testpkg/BuildServerTest.scala +++ b/server-test/src/test/scala/testpkg/BuildServerTest.scala @@ -200,6 +200,19 @@ object BuildServerTest extends AbstractServerTest { }) } + test("buildTarget/resources") { _ => + val x = s"${svr.baseDirectory.getAbsoluteFile.toURI}#util/Compile" + svr.sendJsonRpc( + s"""{ "jsonrpc": "2.0", "id": "23", "method": "buildTarget/resources", "params": { + | "targets": [{ "uri": "$x" }] + |} }""".stripMargin + ) + assert(processing("buildTarget/resources")) + assert(svr.waitForString(10.seconds) { s => + (s contains """"id":"23"""") && (s contains "util/src/main/resources/") + }) + } + private def initializeRequest(): Unit = { svr.sendJsonRpc( """{ "jsonrpc": "2.0", "id": "10", "method": "build/initialize",