add BSP buildTarget/dependencySources

This commit is contained in:
Adrien Piquerez 2020-05-11 09:56:27 +02:00
parent baa47c88c3
commit 24f6a6f290
16 changed files with 287 additions and 23 deletions

View File

@ -342,14 +342,16 @@ object Keys {
val buildTargetIdentifier = settingKey[BuildTargetIdentifier]("Id for BSP build target.").withRank(DSetting)
val bspWorkspace = taskKey[Map[BuildTargetIdentifier, Scope]]("Mapping of BSP build targets to sbt scopes").withRank(DTask)
val bspWorkspaceBuildTargets = taskKey[Seq[BuildTarget]]("List all the BSP build targets").withRank(DTask)
val bspBuildTarget = taskKey[BuildTarget]("Description of the BSP build target").withRank(DTask)
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 bspBuildTargetDependencySources = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetDependencySourcesItem = taskKey[DependencySourcesItem]("").withRank(DTask)
val bspBuildTargetCompile = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetCompileItem = taskKey[Int]("").withRank(DTask)
val bspBuildTargetScalacOptions = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetScalacOptionsItem = taskKey[ScalacOptionsItem]("").withRank(DTask)
val bspInternalDependencyConfigurations = settingKey[Seq[(ProjectRef, Set[String])]]("The project configurations that this configuration depends on, possibly transitivly")
val bspInternalDependencyConfigurations = settingKey[Seq[(ProjectRef, Set[String])]]("The project configurations that this configuration depends on, possibly transitivly").withRank(DTask)
val useCoursier = settingKey[Boolean]("Use Coursier for dependency resolution.").withRank(BSetting)
val csrCacheDirectory = settingKey[File]("Coursier cache directory. Uses -Dsbt.coursier.home or Coursier's default.").withRank(CSetting)

View File

@ -28,7 +28,10 @@ object BuildServerProtocol {
private val bspVersion = "2.0.0-M5"
private val languageIds = Vector("scala")
private val bspTargetConfigs = Set("compile", "test")
private val capabilities = BuildServerCapabilities(CompileProvider(languageIds))
private val capabilities = BuildServerCapabilities(
CompileProvider(languageIds),
dependencySourcesProvider = true
)
lazy val globalSettings: Seq[Def.Setting[_]] = Seq(
bspWorkspace := Def.taskDyn {
@ -66,6 +69,20 @@ object BuildServerProtocol {
}
}.evaluated,
bspBuildTargetSources / aggregate := false,
bspBuildTargetDependencySources := 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 {
import sbt.internal.bsp.codec.JsonProtocol._
val items = bspBuildTargetDependencySourcesItem.all(filter).value
val result = DependencySourcesResult(items.toVector)
s.respondEvent(result)
}
}.evaluated,
bspBuildTargetDependencySources / aggregate := false,
bspBuildTargetCompile := Def.inputTaskDyn {
val s: State = state.value
val workspace = bspWorkspace.value
@ -112,6 +129,7 @@ object BuildServerProtocol {
})
SourcesItem(id, items)
},
bspBuildTargetDependencySourcesItem := dependencySourcesItemTask.value,
bspBuildTargetCompileItem := bspCompileTask.value,
bspBuildTargetScalacOptionsItem := scalacOptionsTask.value,
bspInternalDependencyConfigurations := internalDependencyConfigurationsSetting.value
@ -140,6 +158,12 @@ object BuildServerProtocol {
val command = Keys.bspBuildTargetSources.key
val _ = callback.appendExec(s"$command $targets", Some(r.id))
case r if r.method == "buildTarget/dependencySources" =>
val param = Converter.fromJson[DependencySourcesParams](json(r)).get
val targets = param.targets.map(_.uri).mkString(" ")
val command = Keys.bspBuildTargetDependencySources.key
val _ = callback.appendExec(s"$command $targets", Some(r.id))
case r if r.method == "buildTarget/compile" =>
val param = Converter.fromJson[CompileParams](json(r)).get
callback.log.info(param.toString)
@ -186,7 +210,8 @@ object BuildServerProtocol {
val baseDirectory = Keys.baseDirectory.value.toURI
val projectDependencies = for {
(dep, configs) <- Keys.bspInternalDependencyConfigurations.value
config <- configs if (dep != thisProjectRef || config != thisConfig.name) && bspTargetConfigs.contains(config)
config <- configs
if (dep != thisProjectRef || config != thisConfig.name) && bspTargetConfigs.contains(config)
} yield Keys.buildTargetIdentifier.in(dep, ConfigKey(config))
val capabilities = BuildTargetCapabilities(canCompile = true, canTest = false, canRun = false)
val tags = BuildTargetTag.fromConfig(configuration.name)
@ -228,6 +253,18 @@ object BuildServerProtocol {
}
}
private def dependencySourcesItemTask: Def.Initialize[Task[DependencySourcesItem]] = Def.task {
val targetId = Keys.buildTargetIdentifier.value
val updateReport = Keys.updateClassifiers.value
val sources = for {
configuration <- updateReport.configurations.view
module <- configuration.modules.view
(artifact, file) <- module.artifacts
classifier <- artifact.classifier if classifier == "sources"
} yield file.toURI
DependencySourcesItem(targetId, sources.distinct.toVector)
}
private def bspCompileTask: Def.Initialize[Task[Int]] = Def.task {
import sbt.Project._
Keys.compile.result.value match {

View File

@ -1,27 +1,32 @@
/**
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/** @param compileProvider The languages the server supports compilation via method buildTarget/compile. */
/**
* @param compileProvider The languages the server supports compilation via method buildTarget/compile.
* @param dependencySourcesProvider The server provides sources for library dependencies
via method buildTarget/dependencySources
*/
final class BuildServerCapabilities private (
val compileProvider: Option[sbt.internal.bsp.CompileProvider]) extends Serializable {
val compileProvider: Option[sbt.internal.bsp.CompileProvider],
val dependencySourcesProvider: Option[Boolean]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: BuildServerCapabilities => (this.compileProvider == x.compileProvider)
case x: BuildServerCapabilities => (this.compileProvider == x.compileProvider) && (this.dependencySourcesProvider == x.dependencySourcesProvider)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (17 + "sbt.internal.bsp.BuildServerCapabilities".##) + compileProvider.##)
37 * (37 * (37 * (17 + "sbt.internal.bsp.BuildServerCapabilities".##) + compileProvider.##) + dependencySourcesProvider.##)
}
override def toString: String = {
"BuildServerCapabilities(" + compileProvider + ")"
"BuildServerCapabilities(" + compileProvider + ", " + dependencySourcesProvider + ")"
}
private[this] def copy(compileProvider: Option[sbt.internal.bsp.CompileProvider] = compileProvider): BuildServerCapabilities = {
new BuildServerCapabilities(compileProvider)
private[this] def copy(compileProvider: Option[sbt.internal.bsp.CompileProvider] = compileProvider, dependencySourcesProvider: Option[Boolean] = dependencySourcesProvider): BuildServerCapabilities = {
new BuildServerCapabilities(compileProvider, dependencySourcesProvider)
}
def withCompileProvider(compileProvider: Option[sbt.internal.bsp.CompileProvider]): BuildServerCapabilities = {
copy(compileProvider = compileProvider)
@ -29,9 +34,15 @@ final class BuildServerCapabilities private (
def withCompileProvider(compileProvider: sbt.internal.bsp.CompileProvider): BuildServerCapabilities = {
copy(compileProvider = Option(compileProvider))
}
def withDependencySourcesProvider(dependencySourcesProvider: Option[Boolean]): BuildServerCapabilities = {
copy(dependencySourcesProvider = dependencySourcesProvider)
}
def withDependencySourcesProvider(dependencySourcesProvider: Boolean): BuildServerCapabilities = {
copy(dependencySourcesProvider = Option(dependencySourcesProvider))
}
}
object BuildServerCapabilities {
def apply(compileProvider: Option[sbt.internal.bsp.CompileProvider]): BuildServerCapabilities = new BuildServerCapabilities(compileProvider)
def apply(compileProvider: sbt.internal.bsp.CompileProvider): BuildServerCapabilities = new BuildServerCapabilities(Option(compileProvider))
def apply(compileProvider: Option[sbt.internal.bsp.CompileProvider], dependencySourcesProvider: Option[Boolean]): BuildServerCapabilities = new BuildServerCapabilities(compileProvider, dependencySourcesProvider)
def apply(compileProvider: sbt.internal.bsp.CompileProvider, dependencySourcesProvider: Boolean): BuildServerCapabilities = new BuildServerCapabilities(Option(compileProvider), Option(dependencySourcesProvider))
}

View File

@ -1,5 +1,5 @@
/**
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY

View File

@ -1,5 +1,5 @@
/**
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY

View File

@ -0,0 +1,42 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/** @param sources List of resources containing source files of the target's dependencies.
Can be source files, jar files, zip files, or directories */
final class DependencySourcesItem private (
val target: Option[sbt.internal.bsp.BuildTargetIdentifier],
val sources: Vector[java.net.URI]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: DependencySourcesItem => (this.target == x.target) && (this.sources == x.sources)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (17 + "sbt.internal.bsp.DependencySourcesItem".##) + target.##) + sources.##)
}
override def toString: String = {
"DependencySourcesItem(" + target + ", " + sources + ")"
}
private[this] def copy(target: Option[sbt.internal.bsp.BuildTargetIdentifier] = target, sources: Vector[java.net.URI] = sources): DependencySourcesItem = {
new DependencySourcesItem(target, sources)
}
def withTarget(target: Option[sbt.internal.bsp.BuildTargetIdentifier]): DependencySourcesItem = {
copy(target = target)
}
def withTarget(target: sbt.internal.bsp.BuildTargetIdentifier): DependencySourcesItem = {
copy(target = Option(target))
}
def withSources(sources: Vector[java.net.URI]): DependencySourcesItem = {
copy(sources = sources)
}
}
object DependencySourcesItem {
def apply(target: Option[sbt.internal.bsp.BuildTargetIdentifier], sources: Vector[java.net.URI]): DependencySourcesItem = new DependencySourcesItem(target, sources)
def apply(target: sbt.internal.bsp.BuildTargetIdentifier, sources: Vector[java.net.URI]): DependencySourcesItem = new DependencySourcesItem(Option(target), sources)
}

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
/** Dependency Sources Request */
final class DependencySourcesParams private (
val targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: DependencySourcesParams => (this.targets == x.targets)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (17 + "sbt.internal.bsp.DependencySourcesParams".##) + targets.##)
}
override def toString: String = {
"DependencySourcesParams(" + targets + ")"
}
private[this] def copy(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier] = targets): DependencySourcesParams = {
new DependencySourcesParams(targets)
}
def withTargets(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]): DependencySourcesParams = {
copy(targets = targets)
}
}
object DependencySourcesParams {
def apply(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]): DependencySourcesParams = new DependencySourcesParams(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
/** Dependency Sources Result */
final class DependencySourcesResult private (
val items: Vector[sbt.internal.bsp.DependencySourcesItem]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: DependencySourcesResult => (this.items == x.items)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (17 + "sbt.internal.bsp.DependencySourcesResult".##) + items.##)
}
override def toString: String = {
"DependencySourcesResult(" + items + ")"
}
private[this] def copy(items: Vector[sbt.internal.bsp.DependencySourcesItem] = items): DependencySourcesResult = {
new DependencySourcesResult(items)
}
def withItems(items: Vector[sbt.internal.bsp.DependencySourcesItem]): DependencySourcesResult = {
copy(items = items)
}
}
object DependencySourcesResult {
def apply(items: Vector[sbt.internal.bsp.DependencySourcesItem]): DependencySourcesResult = new DependencySourcesResult(items)
}

View File

@ -1,5 +1,5 @@
/**
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
@ -12,8 +12,9 @@ implicit lazy val BuildServerCapabilitiesFormat: JsonFormat[sbt.internal.bsp.Bui
case Some(__js) =>
unbuilder.beginObject(__js)
val compileProvider = unbuilder.readField[Option[sbt.internal.bsp.CompileProvider]]("compileProvider")
val dependencySourcesProvider = unbuilder.readField[Option[Boolean]]("dependencySourcesProvider")
unbuilder.endObject()
sbt.internal.bsp.BuildServerCapabilities(compileProvider)
sbt.internal.bsp.BuildServerCapabilities(compileProvider, dependencySourcesProvider)
case None =>
deserializationError("Expected JsObject but found None")
}
@ -21,6 +22,7 @@ implicit lazy val BuildServerCapabilitiesFormat: JsonFormat[sbt.internal.bsp.Bui
override def write[J](obj: sbt.internal.bsp.BuildServerCapabilities, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("compileProvider", obj.compileProvider)
builder.addField("dependencySourcesProvider", obj.dependencySourcesProvider)
builder.endObject()
}
}

View File

@ -1,5 +1,5 @@
/**
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY

View File

@ -1,5 +1,5 @@
/**
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY

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 DependencySourcesItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val DependencySourcesItemFormat: JsonFormat[sbt.internal.bsp.DependencySourcesItem] = new JsonFormat[sbt.internal.bsp.DependencySourcesItem] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.DependencySourcesItem = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val target = unbuilder.readField[Option[sbt.internal.bsp.BuildTargetIdentifier]]("target")
val sources = unbuilder.readField[Vector[java.net.URI]]("sources")
unbuilder.endObject()
sbt.internal.bsp.DependencySourcesItem(target, sources)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.DependencySourcesItem, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("target", obj.target)
builder.addField("sources", obj.sources)
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 DependencySourcesParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val DependencySourcesParamsFormat: JsonFormat[sbt.internal.bsp.DependencySourcesParams] = new JsonFormat[sbt.internal.bsp.DependencySourcesParams] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.DependencySourcesParams = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val targets = unbuilder.readField[Vector[sbt.internal.bsp.BuildTargetIdentifier]]("targets")
unbuilder.endObject()
sbt.internal.bsp.DependencySourcesParams(targets)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.DependencySourcesParams, 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 DependencySourcesResultFormats { self: sbt.internal.bsp.codec.DependencySourcesItemFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val DependencySourcesResultFormat: JsonFormat[sbt.internal.bsp.DependencySourcesResult] = new JsonFormat[sbt.internal.bsp.DependencySourcesResult] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.DependencySourcesResult = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val items = unbuilder.readField[Vector[sbt.internal.bsp.DependencySourcesItem]]("items")
unbuilder.endObject()
sbt.internal.bsp.DependencySourcesResult(items)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.DependencySourcesResult, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("items", obj.items)
builder.endObject()
}
}
}

View File

@ -25,6 +25,9 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol
with sbt.internal.bsp.codec.SourceItemFormats
with sbt.internal.bsp.codec.SourcesItemFormats
with sbt.internal.bsp.codec.SourcesResultFormats
with sbt.internal.bsp.codec.DependencySourcesParamsFormats
with sbt.internal.bsp.codec.DependencySourcesItemFormats
with sbt.internal.bsp.codec.DependencySourcesResultFormats
with sbt.internal.bsp.codec.TaskStartParamsFormats
with sbt.internal.bsp.codec.TaskFinishParamsFormats
with sbt.internal.bsp.codec.CompileParamsFormats

View File

@ -178,9 +178,9 @@ type BuildServerCapabilities {
# single text document via the method buildTarget/inverseSources
# inverseSourcesProvider: Boolean
# The server provides sources for library dependencies
# via method buildTarget/dependencySources
# dependencySourcesProvider: Boolean
## The server provides sources for library dependencies
## via method buildTarget/dependencySources
dependencySourcesProvider: Boolean
# The server provides all the resource dependencies
# via method buildTarget/resources
@ -254,6 +254,24 @@ type SourceItem {
generated: Boolean!
}
## Dependency Sources Request
type DependencySourcesParams {
targets: [sbt.internal.bsp.BuildTargetIdentifier]
}
## Dependency Sources Result
type DependencySourcesResult {
items: [sbt.internal.bsp.DependencySourcesItem]
}
type DependencySourcesItem {
target: sbt.internal.bsp.BuildTargetIdentifier
## List of resources containing source files of the target's dependencies.
## Can be source files, jar files, zip files, or directories
sources: [java.net.URI]
}
## Task Notifications
type TaskStartParams {