Add support for BSP's buildTarget/outputPaths method

This commit is contained in:
Krzysztof Pado 2022-07-27 19:40:18 -07:00 committed by Adrien Piquerez
parent 1f29c9053c
commit 2bffb2731e
23 changed files with 486 additions and 12 deletions

View File

@ -412,6 +412,8 @@ object Keys {
val bspBuildTargetResourcesItem = taskKey[ResourcesItem]("").withRank(DTask) val bspBuildTargetResourcesItem = taskKey[ResourcesItem]("").withRank(DTask)
val bspBuildTargetDependencySources = inputKey[Unit]("").withRank(DTask) val bspBuildTargetDependencySources = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetDependencySourcesItem = taskKey[DependencySourcesItem]("").withRank(DTask) val bspBuildTargetDependencySourcesItem = taskKey[DependencySourcesItem]("").withRank(DTask)
val bspBuildTargetOutputPaths = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetOutputPathsItem = taskKey[OutputPathsItem]("").withRank(DTask)
val bspBuildTargetCompile = inputKey[Unit]("").withRank(DTask) val bspBuildTargetCompile = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetCompileItem = taskKey[Int]("").withRank(DTask) val bspBuildTargetCompileItem = taskKey[Int]("").withRank(DTask)
val bspBuildTargetTest = inputKey[Unit]("Corresponds to buildTarget/test request").withRank(DTask) val bspBuildTargetTest = inputKey[Unit]("Corresponds to buildTarget/test request").withRank(DTask)

View File

@ -52,6 +52,7 @@ object BuildServerProtocol {
RunProvider(BuildServerConnection.languages), RunProvider(BuildServerConnection.languages),
dependencySourcesProvider = true, dependencySourcesProvider = true,
resourcesProvider = true, resourcesProvider = true,
outputPathsProvider = true,
canReload = true, canReload = true,
jvmRunEnvironmentProvider = true, jvmRunEnvironmentProvider = true,
jvmTestEnvironmentProvider = true, jvmTestEnvironmentProvider = true,
@ -158,6 +159,16 @@ object BuildServerProtocol {
} }
}.evaluated, }.evaluated,
bspBuildTargetDependencySources / aggregate := false, bspBuildTargetDependencySources / aggregate := false,
bspBuildTargetOutputPaths := bspInputTask { (state, _, workspace, filter) =>
Def.task {
import sbt.internal.bsp.codec.JsonProtocol._
val items = bspBuildTargetOutputPathsItem.result.all(filter).value
val successfulItems = anyOrThrow(items)
val result = OutputPathsResult(successfulItems.toVector)
state.respondEvent(result)
}
}.evaluated,
bspBuildTargetOutputPaths / aggregate := false,
bspBuildTargetCompile := bspInputTask { (state, _, workspace, filter) => bspBuildTargetCompile := bspInputTask { (state, _, workspace, filter) =>
workspace.warnIfBuildsNonEmpty(Method.Compile, state.log) workspace.warnIfBuildsNonEmpty(Method.Compile, state.log)
Def.task { Def.task {
@ -267,6 +278,10 @@ object BuildServerProtocol {
ResourcesItem(id, uris) ResourcesItem(id, uris)
}, },
bspBuildTargetDependencySourcesItem := dependencySourcesItemTask.value, bspBuildTargetDependencySourcesItem := dependencySourcesItemTask.value,
bspBuildTargetOutputPathsItem := {
val id = bspTargetIdentifier.value
OutputPathsItem(id, Vector(OutputPathItem(target.value.toURI, OutputPathItemKind.Directory)))
},
bspBuildTargetCompileItem := bspCompileTask.value, bspBuildTargetCompileItem := bspCompileTask.value,
bspBuildTargetRun := bspRunTask.evaluated, bspBuildTargetRun := bspRunTask.evaluated,
bspBuildTargetScalacOptionsItem := scalacOptionsTask.value, bspBuildTargetScalacOptionsItem := scalacOptionsTask.value,
@ -318,6 +333,7 @@ object BuildServerProtocol {
final val Shutdown = "build/shutdown" final val Shutdown = "build/shutdown"
final val Sources = "buildTarget/sources" final val Sources = "buildTarget/sources"
final val Resources = "buildTarget/resources" final val Resources = "buildTarget/resources"
final val OutputPaths = "buildTarget/outputPaths"
final val DependencySources = "buildTarget/dependencySources" final val DependencySources = "buildTarget/dependencySources"
final val Compile = "buildTarget/compile" final val Compile = "buildTarget/compile"
final val Test = "buildTarget/test" final val Test = "buildTarget/test"
@ -453,6 +469,12 @@ object BuildServerProtocol {
val targets = param.targets.map(_.uri).mkString(" ") val targets = param.targets.map(_.uri).mkString(" ")
val command = Keys.bspBuildTargetResources.key val command = Keys.bspBuildTargetResources.key
val _ = callback.appendExec(s"$command $targets", Some(r.id)) val _ = callback.appendExec(s"$command $targets", Some(r.id))
case r if r.method == Method.OutputPaths =>
val param = Converter.fromJson[OutputPathsParams](json(r)).get
val targets = param.targets.map(_.uri).mkString(" ")
val command = Keys.bspBuildTargetOutputPaths.key
val _ = callback.appendExec(s"$command $targets", Some(r.id))
}, },
onResponse = PartialFunction.empty, onResponse = PartialFunction.empty,
onNotification = { onNotification = {

View File

@ -0,0 +1,4 @@
[@povder]: https://github.com/povder
### Improvements
- Add support for newly introduced `buildTarget/outputPaths` method of BSP protocol. See [bsp#269](https://github.com/build-server-protocol/build-server-protocol/pull/269) pull request and [bsp#205](https://github.com/build-server-protocol/build-server-protocol/issues/205) issue.

View File

@ -17,6 +17,7 @@ final class BuildServerCapabilities private (
val runProvider: Option[sbt.internal.bsp.RunProvider], val runProvider: Option[sbt.internal.bsp.RunProvider],
val dependencySourcesProvider: Option[Boolean], val dependencySourcesProvider: Option[Boolean],
val resourcesProvider: Option[Boolean], val resourcesProvider: Option[Boolean],
val outputPathsProvider: Option[Boolean],
val canReload: Option[Boolean], val canReload: Option[Boolean],
val jvmRunEnvironmentProvider: Option[Boolean], val jvmRunEnvironmentProvider: Option[Boolean],
val jvmTestEnvironmentProvider: Option[Boolean]) extends Serializable { val jvmTestEnvironmentProvider: Option[Boolean]) extends Serializable {
@ -24,17 +25,17 @@ final class BuildServerCapabilities private (
override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
case x: BuildServerCapabilities => (this.compileProvider == x.compileProvider) && (this.testProvider == x.testProvider) && (this.runProvider == x.runProvider) && (this.dependencySourcesProvider == x.dependencySourcesProvider) && (this.resourcesProvider == x.resourcesProvider) && (this.canReload == x.canReload) && (this.jvmRunEnvironmentProvider == x.jvmRunEnvironmentProvider) && (this.jvmTestEnvironmentProvider == x.jvmTestEnvironmentProvider) case x: BuildServerCapabilities => (this.compileProvider == x.compileProvider) && (this.testProvider == x.testProvider) && (this.runProvider == x.runProvider) && (this.dependencySourcesProvider == x.dependencySourcesProvider) && (this.resourcesProvider == x.resourcesProvider) && (this.outputPathsProvider == x.outputPathsProvider) && (this.canReload == x.canReload) && (this.jvmRunEnvironmentProvider == x.jvmRunEnvironmentProvider) && (this.jvmTestEnvironmentProvider == x.jvmTestEnvironmentProvider)
case _ => false case _ => false
}) })
override def hashCode: Int = { override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.BuildServerCapabilities".##) + compileProvider.##) + testProvider.##) + runProvider.##) + dependencySourcesProvider.##) + resourcesProvider.##) + canReload.##) + jvmRunEnvironmentProvider.##) + jvmTestEnvironmentProvider.##) 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.BuildServerCapabilities".##) + compileProvider.##) + testProvider.##) + runProvider.##) + dependencySourcesProvider.##) + resourcesProvider.##) + outputPathsProvider.##) + canReload.##) + jvmRunEnvironmentProvider.##) + jvmTestEnvironmentProvider.##)
} }
override def toString: String = { override def toString: String = {
"BuildServerCapabilities(" + compileProvider + ", " + testProvider + ", " + runProvider + ", " + dependencySourcesProvider + ", " + resourcesProvider + ", " + canReload + ", " + jvmRunEnvironmentProvider + ", " + jvmTestEnvironmentProvider + ")" "BuildServerCapabilities(" + compileProvider + ", " + testProvider + ", " + runProvider + ", " + dependencySourcesProvider + ", " + resourcesProvider + ", " + outputPathsProvider + ", " + canReload + ", " + jvmRunEnvironmentProvider + ", " + jvmTestEnvironmentProvider + ")"
} }
private[this] def copy(compileProvider: Option[sbt.internal.bsp.CompileProvider] = compileProvider, testProvider: Option[sbt.internal.bsp.TestProvider] = testProvider, runProvider: Option[sbt.internal.bsp.RunProvider] = runProvider, dependencySourcesProvider: Option[Boolean] = dependencySourcesProvider, resourcesProvider: Option[Boolean] = resourcesProvider, canReload: Option[Boolean] = canReload, jvmRunEnvironmentProvider: Option[Boolean] = jvmRunEnvironmentProvider, jvmTestEnvironmentProvider: Option[Boolean] = jvmTestEnvironmentProvider): BuildServerCapabilities = { private[this] def copy(compileProvider: Option[sbt.internal.bsp.CompileProvider] = compileProvider, testProvider: Option[sbt.internal.bsp.TestProvider] = testProvider, runProvider: Option[sbt.internal.bsp.RunProvider] = runProvider, dependencySourcesProvider: Option[Boolean] = dependencySourcesProvider, resourcesProvider: Option[Boolean] = resourcesProvider, outputPathsProvider: Option[Boolean] = outputPathsProvider, canReload: Option[Boolean] = canReload, jvmRunEnvironmentProvider: Option[Boolean] = jvmRunEnvironmentProvider, jvmTestEnvironmentProvider: Option[Boolean] = jvmTestEnvironmentProvider): BuildServerCapabilities = {
new BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) new BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, outputPathsProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider)
} }
def withCompileProvider(compileProvider: Option[sbt.internal.bsp.CompileProvider]): BuildServerCapabilities = { def withCompileProvider(compileProvider: Option[sbt.internal.bsp.CompileProvider]): BuildServerCapabilities = {
copy(compileProvider = compileProvider) copy(compileProvider = compileProvider)
@ -66,6 +67,12 @@ final class BuildServerCapabilities private (
def withResourcesProvider(resourcesProvider: Boolean): BuildServerCapabilities = { def withResourcesProvider(resourcesProvider: Boolean): BuildServerCapabilities = {
copy(resourcesProvider = Option(resourcesProvider)) copy(resourcesProvider = Option(resourcesProvider))
} }
def withOutputPathsProvider(outputPathsProvider: Option[Boolean]): BuildServerCapabilities = {
copy(outputPathsProvider = outputPathsProvider)
}
def withOutputPathsProvider(outputPathsProvider: Boolean): BuildServerCapabilities = {
copy(outputPathsProvider = Option(outputPathsProvider))
}
def withCanReload(canReload: Option[Boolean]): BuildServerCapabilities = { def withCanReload(canReload: Option[Boolean]): BuildServerCapabilities = {
copy(canReload = canReload) copy(canReload = canReload)
} }
@ -87,6 +94,6 @@ final class BuildServerCapabilities private (
} }
object BuildServerCapabilities { object BuildServerCapabilities {
def apply(compileProvider: Option[sbt.internal.bsp.CompileProvider], testProvider: Option[sbt.internal.bsp.TestProvider], runProvider: Option[sbt.internal.bsp.RunProvider], dependencySourcesProvider: Option[Boolean], resourcesProvider: Option[Boolean], canReload: Option[Boolean], jvmRunEnvironmentProvider: Option[Boolean], jvmTestEnvironmentProvider: Option[Boolean]): BuildServerCapabilities = new BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) def apply(compileProvider: Option[sbt.internal.bsp.CompileProvider], testProvider: Option[sbt.internal.bsp.TestProvider], runProvider: Option[sbt.internal.bsp.RunProvider], dependencySourcesProvider: Option[Boolean], resourcesProvider: Option[Boolean], outputPathsProvider: Option[Boolean], canReload: Option[Boolean], jvmRunEnvironmentProvider: Option[Boolean], jvmTestEnvironmentProvider: Option[Boolean]): BuildServerCapabilities = new BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, outputPathsProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider)
def apply(compileProvider: sbt.internal.bsp.CompileProvider, testProvider: sbt.internal.bsp.TestProvider, runProvider: sbt.internal.bsp.RunProvider, dependencySourcesProvider: Boolean, resourcesProvider: Boolean, canReload: Boolean, jvmRunEnvironmentProvider: Boolean, jvmTestEnvironmentProvider: Boolean): BuildServerCapabilities = new BuildServerCapabilities(Option(compileProvider), Option(testProvider), Option(runProvider), Option(dependencySourcesProvider), Option(resourcesProvider), Option(canReload), Option(jvmRunEnvironmentProvider), Option(jvmTestEnvironmentProvider)) def apply(compileProvider: sbt.internal.bsp.CompileProvider, testProvider: sbt.internal.bsp.TestProvider, runProvider: sbt.internal.bsp.RunProvider, dependencySourcesProvider: Boolean, resourcesProvider: Boolean, outputPathsProvider: Boolean, canReload: Boolean, jvmRunEnvironmentProvider: Boolean, jvmTestEnvironmentProvider: Boolean): BuildServerCapabilities = new BuildServerCapabilities(Option(compileProvider), Option(testProvider), Option(runProvider), Option(dependencySourcesProvider), Option(resourcesProvider), Option(outputPathsProvider), Option(canReload), Option(jvmRunEnvironmentProvider), Option(jvmTestEnvironmentProvider))
} }

View File

@ -0,0 +1,36 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
final class OutputPathItem private (
val uri: java.net.URI,
val kind: Int) extends Serializable {
override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
case x: OutputPathItem => (this.uri == x.uri) && (this.kind == x.kind)
case _ => false
})
override def hashCode: Int = {
37 * (37 * (37 * (17 + "sbt.internal.bsp.OutputPathItem".##) + uri.##) + kind.##)
}
override def toString: String = {
"OutputPathItem(" + uri + ", " + kind + ")"
}
private[this] def copy(uri: java.net.URI = uri, kind: Int = kind): OutputPathItem = {
new OutputPathItem(uri, kind)
}
def withUri(uri: java.net.URI): OutputPathItem = {
copy(uri = uri)
}
def withKind(kind: Int): OutputPathItem = {
copy(kind = kind)
}
}
object OutputPathItem {
def apply(uri: java.net.URI, kind: Int): OutputPathItem = new OutputPathItem(uri, kind)
}

View File

@ -0,0 +1,36 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
final class OutputPathsItem private (
val target: sbt.internal.bsp.BuildTargetIdentifier,
val outputPaths: Vector[sbt.internal.bsp.OutputPathItem]) extends Serializable {
override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
case x: OutputPathsItem => (this.target == x.target) && (this.outputPaths == x.outputPaths)
case _ => false
})
override def hashCode: Int = {
37 * (37 * (37 * (17 + "sbt.internal.bsp.OutputPathsItem".##) + target.##) + outputPaths.##)
}
override def toString: String = {
"OutputPathsItem(" + target + ", " + outputPaths + ")"
}
private[this] def copy(target: sbt.internal.bsp.BuildTargetIdentifier = target, outputPaths: Vector[sbt.internal.bsp.OutputPathItem] = outputPaths): OutputPathsItem = {
new OutputPathsItem(target, outputPaths)
}
def withTarget(target: sbt.internal.bsp.BuildTargetIdentifier): OutputPathsItem = {
copy(target = target)
}
def withOutputPaths(outputPaths: Vector[sbt.internal.bsp.OutputPathItem]): OutputPathsItem = {
copy(outputPaths = outputPaths)
}
}
object OutputPathsItem {
def apply(target: sbt.internal.bsp.BuildTargetIdentifier, outputPaths: Vector[sbt.internal.bsp.OutputPathItem]): OutputPathsItem = new OutputPathsItem(target, outputPaths)
}

View File

@ -0,0 +1,33 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/** Build Target OutputPaths Request */
final class OutputPathsParams private (
val targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]) extends Serializable {
override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
case x: OutputPathsParams => (this.targets == x.targets)
case _ => false
})
override def hashCode: Int = {
37 * (37 * (17 + "sbt.internal.bsp.OutputPathsParams".##) + targets.##)
}
override def toString: String = {
"OutputPathsParams(" + targets + ")"
}
private[this] def copy(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier] = targets): OutputPathsParams = {
new OutputPathsParams(targets)
}
def withTargets(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]): OutputPathsParams = {
copy(targets = targets)
}
}
object OutputPathsParams {
def apply(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]): OutputPathsParams = new OutputPathsParams(targets)
}

View File

@ -0,0 +1,33 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/** Build Target OutputPaths response */
final class OutputPathsResult private (
val items: Vector[sbt.internal.bsp.OutputPathsItem]) extends Serializable {
override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
case x: OutputPathsResult => (this.items == x.items)
case _ => false
})
override def hashCode: Int = {
37 * (37 * (17 + "sbt.internal.bsp.OutputPathsResult".##) + items.##)
}
override def toString: String = {
"OutputPathsResult(" + items + ")"
}
private[this] def copy(items: Vector[sbt.internal.bsp.OutputPathsItem] = items): OutputPathsResult = {
new OutputPathsResult(items)
}
def withItems(items: Vector[sbt.internal.bsp.OutputPathsItem]): OutputPathsResult = {
copy(items = items)
}
}
object OutputPathsResult {
def apply(items: Vector[sbt.internal.bsp.OutputPathsItem]): OutputPathsResult = new OutputPathsResult(items)
}

View File

@ -16,11 +16,12 @@ implicit lazy val BuildServerCapabilitiesFormat: JsonFormat[sbt.internal.bsp.Bui
val runProvider = unbuilder.readField[Option[sbt.internal.bsp.RunProvider]]("runProvider") val runProvider = unbuilder.readField[Option[sbt.internal.bsp.RunProvider]]("runProvider")
val dependencySourcesProvider = unbuilder.readField[Option[Boolean]]("dependencySourcesProvider") val dependencySourcesProvider = unbuilder.readField[Option[Boolean]]("dependencySourcesProvider")
val resourcesProvider = unbuilder.readField[Option[Boolean]]("resourcesProvider") val resourcesProvider = unbuilder.readField[Option[Boolean]]("resourcesProvider")
val outputPathsProvider = unbuilder.readField[Option[Boolean]]("outputPathsProvider")
val canReload = unbuilder.readField[Option[Boolean]]("canReload") val canReload = unbuilder.readField[Option[Boolean]]("canReload")
val jvmRunEnvironmentProvider = unbuilder.readField[Option[Boolean]]("jvmRunEnvironmentProvider") val jvmRunEnvironmentProvider = unbuilder.readField[Option[Boolean]]("jvmRunEnvironmentProvider")
val jvmTestEnvironmentProvider = unbuilder.readField[Option[Boolean]]("jvmTestEnvironmentProvider") val jvmTestEnvironmentProvider = unbuilder.readField[Option[Boolean]]("jvmTestEnvironmentProvider")
unbuilder.endObject() unbuilder.endObject()
sbt.internal.bsp.BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider) sbt.internal.bsp.BuildServerCapabilities(compileProvider, testProvider, runProvider, dependencySourcesProvider, resourcesProvider, outputPathsProvider, canReload, jvmRunEnvironmentProvider, jvmTestEnvironmentProvider)
case None => case None =>
deserializationError("Expected JsObject but found None") deserializationError("Expected JsObject but found None")
} }
@ -32,6 +33,7 @@ implicit lazy val BuildServerCapabilitiesFormat: JsonFormat[sbt.internal.bsp.Bui
builder.addField("runProvider", obj.runProvider) builder.addField("runProvider", obj.runProvider)
builder.addField("dependencySourcesProvider", obj.dependencySourcesProvider) builder.addField("dependencySourcesProvider", obj.dependencySourcesProvider)
builder.addField("resourcesProvider", obj.resourcesProvider) builder.addField("resourcesProvider", obj.resourcesProvider)
builder.addField("outputPathsProvider", obj.outputPathsProvider)
builder.addField("canReload", obj.canReload) builder.addField("canReload", obj.canReload)
builder.addField("jvmRunEnvironmentProvider", obj.jvmRunEnvironmentProvider) builder.addField("jvmRunEnvironmentProvider", obj.jvmRunEnvironmentProvider)
builder.addField("jvmTestEnvironmentProvider", obj.jvmTestEnvironmentProvider) builder.addField("jvmTestEnvironmentProvider", obj.jvmTestEnvironmentProvider)

View File

@ -0,0 +1,29 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait ExcludeItemFormats { self: sjsonnew.BasicJsonProtocol =>
implicit lazy val ExcludeItemFormat: JsonFormat[sbt.internal.bsp.ExcludeItem] = new JsonFormat[sbt.internal.bsp.ExcludeItem] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ExcludeItem = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val uri = unbuilder.readField[java.net.URI]("uri")
val kind = unbuilder.readField[Int]("kind")
unbuilder.endObject()
sbt.internal.bsp.ExcludeItem(uri, kind)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.ExcludeItem, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("uri", obj.uri)
builder.addField("kind", obj.kind)
builder.endObject()
}
}
}

View File

@ -0,0 +1,29 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait ExcludesItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.ExcludeItemFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val ExcludesItemFormat: JsonFormat[sbt.internal.bsp.ExcludesItem] = new JsonFormat[sbt.internal.bsp.ExcludesItem] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ExcludesItem = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val target = unbuilder.readField[sbt.internal.bsp.BuildTargetIdentifier]("target")
val excludes = unbuilder.readField[Vector[sbt.internal.bsp.ExcludeItem]]("excludes")
unbuilder.endObject()
sbt.internal.bsp.ExcludesItem(target, excludes)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.ExcludesItem, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("target", obj.target)
builder.addField("excludes", obj.excludes)
builder.endObject()
}
}
}

View File

@ -0,0 +1,27 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait ExcludesParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val ExcludesParamsFormat: JsonFormat[sbt.internal.bsp.ExcludesParams] = new JsonFormat[sbt.internal.bsp.ExcludesParams] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ExcludesParams = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val targets = unbuilder.readField[Vector[sbt.internal.bsp.BuildTargetIdentifier]]("targets")
unbuilder.endObject()
sbt.internal.bsp.ExcludesParams(targets)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.ExcludesParams, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("targets", obj.targets)
builder.endObject()
}
}
}

View File

@ -0,0 +1,27 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait ExcludesResultFormats { self: sbt.internal.bsp.codec.ExcludesItemFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val ExcludesResultFormat: JsonFormat[sbt.internal.bsp.ExcludesResult] = new JsonFormat[sbt.internal.bsp.ExcludesResult] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ExcludesResult = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val items = unbuilder.readField[Vector[sbt.internal.bsp.ExcludesItem]]("items")
unbuilder.endObject()
sbt.internal.bsp.ExcludesResult(items)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.ExcludesResult, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("items", obj.items)
builder.endObject()
}
}
}

View File

@ -29,6 +29,10 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol
with sbt.internal.bsp.codec.SourceItemFormats with sbt.internal.bsp.codec.SourceItemFormats
with sbt.internal.bsp.codec.SourcesItemFormats with sbt.internal.bsp.codec.SourcesItemFormats
with sbt.internal.bsp.codec.SourcesResultFormats with sbt.internal.bsp.codec.SourcesResultFormats
with sbt.internal.bsp.codec.OutputPathsParamsFormats
with sbt.internal.bsp.codec.OutputPathItemFormats
with sbt.internal.bsp.codec.OutputPathsItemFormats
with sbt.internal.bsp.codec.OutputPathsResultFormats
with sbt.internal.bsp.codec.DependencySourcesParamsFormats with sbt.internal.bsp.codec.DependencySourcesParamsFormats
with sbt.internal.bsp.codec.DependencySourcesItemFormats with sbt.internal.bsp.codec.DependencySourcesItemFormats
with sbt.internal.bsp.codec.DependencySourcesResultFormats with sbt.internal.bsp.codec.DependencySourcesResultFormats

View File

@ -0,0 +1,29 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait OutputPathItemFormats { self: sjsonnew.BasicJsonProtocol =>
implicit lazy val OutputPathItemFormat: JsonFormat[sbt.internal.bsp.OutputPathItem] = new JsonFormat[sbt.internal.bsp.OutputPathItem] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.OutputPathItem = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val uri = unbuilder.readField[java.net.URI]("uri")
val kind = unbuilder.readField[Int]("kind")
unbuilder.endObject()
sbt.internal.bsp.OutputPathItem(uri, kind)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.OutputPathItem, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("uri", obj.uri)
builder.addField("kind", obj.kind)
builder.endObject()
}
}
}

View File

@ -0,0 +1,29 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait OutputPathsItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sbt.internal.bsp.codec.OutputPathItemFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val OutputPathsItemFormat: JsonFormat[sbt.internal.bsp.OutputPathsItem] = new JsonFormat[sbt.internal.bsp.OutputPathsItem] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.OutputPathsItem = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val target = unbuilder.readField[sbt.internal.bsp.BuildTargetIdentifier]("target")
val outputPaths = unbuilder.readField[Vector[sbt.internal.bsp.OutputPathItem]]("outputPaths")
unbuilder.endObject()
sbt.internal.bsp.OutputPathsItem(target, outputPaths)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.OutputPathsItem, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("target", obj.target)
builder.addField("outputPaths", obj.outputPaths)
builder.endObject()
}
}
}

View File

@ -0,0 +1,27 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait OutputPathsParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val OutputPathsParamsFormat: JsonFormat[sbt.internal.bsp.OutputPathsParams] = new JsonFormat[sbt.internal.bsp.OutputPathsParams] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.OutputPathsParams = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val targets = unbuilder.readField[Vector[sbt.internal.bsp.BuildTargetIdentifier]]("targets")
unbuilder.endObject()
sbt.internal.bsp.OutputPathsParams(targets)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.OutputPathsParams, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("targets", obj.targets)
builder.endObject()
}
}
}

View File

@ -0,0 +1,27 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait OutputPathsResultFormats { self: sbt.internal.bsp.codec.OutputPathsItemFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val OutputPathsResultFormat: JsonFormat[sbt.internal.bsp.OutputPathsResult] = new JsonFormat[sbt.internal.bsp.OutputPathsResult] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.OutputPathsResult = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val items = unbuilder.readField[Vector[sbt.internal.bsp.OutputPathsItem]]("items")
unbuilder.endObject()
sbt.internal.bsp.OutputPathsResult(items)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.OutputPathsResult, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("items", obj.items)
builder.endObject()
}
}
}

View File

@ -202,6 +202,10 @@ type BuildServerCapabilities {
# via method buildTarget/resources # via method buildTarget/resources
resourcesProvider: Boolean resourcesProvider: Boolean
# The server provides output paths
# via method buildTarget/outputPaths
outputPathsProvider: Boolean
## Reloading the workspace state through workspace/reload is supported ## Reloading the workspace state through workspace/reload is supported
canReload: Boolean canReload: Boolean
@ -290,6 +294,26 @@ type SourceItem {
generated: Boolean! generated: Boolean!
} }
## Build Target OutputPaths Request
type OutputPathsParams {
targets: [sbt.internal.bsp.BuildTargetIdentifier]
}
## Build Target OutputPaths response
type OutputPathsResult {
items: [sbt.internal.bsp.OutputPathsItem]
}
type OutputPathsItem {
target: sbt.internal.bsp.BuildTargetIdentifier!
outputPaths: [sbt.internal.bsp.OutputPathItem]
}
type OutputPathItem {
uri: java.net.URI!
kind: Int!
}
## Dependency Sources Request ## Dependency Sources Request
type DependencySourcesParams { type DependencySourcesParams {
targets: [sbt.internal.bsp.BuildTargetIdentifier] targets: [sbt.internal.bsp.BuildTargetIdentifier]

View File

@ -17,7 +17,7 @@ import scala.util.Properties
object BuildServerConnection { object BuildServerConnection {
final val name = "sbt" final val name = "sbt"
final val bspVersion = "2.0.0-M5" final val bspVersion = "2.1.0-M1"
final val languages = Vector("scala") final val languages = Vector("scala")
private final val SbtLaunchJar = "sbt-launch(-.*)?\\.jar".r private final val SbtLaunchJar = "sbt-launch(-.*)?\\.jar".r

View File

@ -0,0 +1,17 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.internal.bsp
object OutputPathItemKind {
/** The output path item references a normal file. */
val File: Int = 1
/** The output path item references a directory. */
val Directory: Int = 2
}

View File

@ -30,7 +30,9 @@ lazy val respondError = project.in(file("respond-error"))
} }
) )
lazy val util = project lazy val util = project.settings(
Compile / target := baseDirectory.value / "custom-target",
)
lazy val diagnostics = project lazy val diagnostics = project
@ -44,6 +46,7 @@ lazy val badBuildTarget = project.in(file("bad-build-target"))
Compile / bspBuildTargetDependencySourcesItem := somethingBad, Compile / bspBuildTargetDependencySourcesItem := somethingBad,
Compile / bspBuildTargetScalacOptionsItem := somethingBad, Compile / bspBuildTargetScalacOptionsItem := somethingBad,
Compile / bspBuildTargetCompileItem := somethingBad, Compile / bspBuildTargetCompileItem := somethingBad,
Compile / bspBuildTargetOutputPathsItem := somethingBad,
Compile / bspScalaMainClasses := somethingBad, Compile / bspScalaMainClasses := somethingBad,
Test / bspBuildTarget := somethingBad, Test / bspBuildTarget := somethingBad,
Test / bspScalaTestClasses := somethingBad, Test / bspScalaTestClasses := somethingBad,

View File

@ -31,7 +31,8 @@ object BuildServerTest extends AbstractServerTest {
initializeRequest() initializeRequest()
assert(svr.waitForString(10.seconds) { s => assert(svr.waitForString(10.seconds) { s =>
(s contains """"id":"8"""") && (s contains """"id":"8"""") &&
(s contains """"resourcesProvider":true""") (s contains """"resourcesProvider":true""") &&
(s contains """"outputPathsProvider":true""")
}) })
} }
@ -538,13 +539,39 @@ object BuildServerTest extends AbstractServerTest {
}) })
} }
test("buildTarget/outputPaths") { _ =>
val buildTarget = buildTargetUri("util", "Compile")
val badBuildTarget = buildTargetUri("badBuildTarget", "Compile")
svr.sendJsonRpc(
s"""{ "jsonrpc": "2.0", "id": "97", "method": "buildTarget/outputPaths", "params": {
| "targets": [{ "uri": "$buildTarget" }, { "uri": "$badBuildTarget" }]
|} }""".stripMargin
)
assert(processing("buildTarget/outputPaths"))
val actualResult = svr.waitFor[OutputPathsResult](10.seconds)
val expectedResult = OutputPathsResult(
items = Vector(
OutputPathsItem(
target = BuildTargetIdentifier(buildTarget),
outputPaths = Vector(
OutputPathItem(
uri = new File(svr.baseDirectory, "util/custom-target").toURI,
kind = OutputPathItemKind.Directory
)
)
)
)
)
assert(actualResult == expectedResult)
}
private def initializeRequest(): Unit = { private def initializeRequest(): Unit = {
svr.sendJsonRpc( svr.sendJsonRpc(
"""{ "jsonrpc": "2.0", "id": "8", "method": "build/initialize", """{ "jsonrpc": "2.0", "id": "8", "method": "build/initialize",
| "params": { | "params": {
| "displayName": "test client", | "displayName": "test client",
| "version": "1.0.0", | "version": "1.0.0",
| "bspVersion": "2.0.0-M5", | "bspVersion": "2.1.0-M1",
| "rootUri": "file://root/", | "rootUri": "file://root/",
| "capabilities": { "languageIds": ["scala"] } | "capabilities": { "languageIds": ["scala"] }
| } | }