feat: implement BSP's JVM environment requests

This commit is contained in:
Kamil Podsiadlo 2022-03-31 23:26:41 +02:00 committed by Kamil Podsiadło
parent 4f3ff52f6e
commit 5ea12485c6
2 changed files with 73 additions and 0 deletions

View File

@ -396,6 +396,7 @@ object Keys {
val usePipelining = settingKey[Boolean]("Use subproject pipelining for compilation.").withRank(BSetting)
val exportPipelining = settingKey[Boolean]("Product early output so downstream subprojects can do pipelining.").withRank(BSetting)
// BSP keys
val bspConfig = taskKey[Unit]("Create or update the BSP connection files").withRank(DSetting)
val bspEnabled = SettingKey[Boolean](BasicKeys.bspEnabled)
val bspSbtEnabled = settingKey[Boolean]("Should BSP export meta-targets for the SBT build itself?")
@ -418,6 +419,11 @@ object Keys {
val bspBuildTargetCleanCache = inputKey[Unit]("Corresponds to buildTarget/cleanCache request").withRank(DTask)
val bspBuildTargetScalacOptions = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetScalacOptionsItem = taskKey[ScalacOptionsItem]("").withRank(DTask)
val bspBuildTargetJVMRunEnvironment = inputKey[Unit]("Corresponds to the buildTarget/jvmRunEnvironment request").withRank(DTask)
val bspBuildTargetJVMTestEnvironment = inputKey[Unit]("Corresponds to the buildTarget/jvmTestEnvironment request").withRank(DTask)
val bspBuildTargetJvmEnvironmentItem = taskKey[JvmEnvironmentItem]("Computes JVM environment item").withRank(DTask)
val bspScalaTestClasses = inputKey[Unit]("Corresponds to buildTarget/scalaTestClasses request").withRank(DTask)
val bspScalaTestClassesItem = taskKey[Seq[ScalaTestClassesItem]]("").withRank(DTask)
val bspScalaMainClasses = inputKey[Unit]("Corresponds to buildTarget/scalaMainClasses request").withRank(DTask)

View File

@ -315,6 +315,31 @@ object BuildServerProtocol {
bspBuildTargetCompileItem := bspCompileTask.value,
bspBuildTargetRun := bspRunTask.evaluated,
bspBuildTargetScalacOptionsItem := scalacOptionsTask.value,
bspBuildTargetJVMRunEnvironment := Def.inputTaskDyn {
val s = state.value
val targets = spaceDelimited().parsed.map(uri => BuildTargetIdentifier(URI.create(uri)))
val workspace = bspFullWorkspace.value.filter(targets)
val filter = ScopeFilter.in(workspace.scopes.values.toList)
Def.task {
val items = bspBuildTargetJvmEnvironmentItem.result.all(filter).value
val successfulItems = anyOrThrow(items)
val result = JvmRunEnvironmentResult(successfulItems.toVector, None)
s.respondEvent(result)
}
}.evaluated,
bspBuildTargetJVMTestEnvironment := Def.inputTaskDyn {
val s = state.value
val targets = spaceDelimited().parsed.map(uri => BuildTargetIdentifier(URI.create(uri)))
val workspace = bspFullWorkspace.value.filter(targets)
val filter = ScopeFilter.in(workspace.scopes.values.toList)
Def.task {
val items = bspBuildTargetJvmEnvironmentItem.result.all(filter).value
val successfulItems = anyOrThrow(items)
val result = JvmTestEnvironmentResult(successfulItems.toVector, None)
s.respondEvent(result)
}
}.evaluated,
bspBuildTargetJvmEnvironmentItem := jvmEnvironmentItem().value,
bspInternalDependencyConfigurations := internalDependencyConfigurationsSetting.value,
bspScalaTestClassesItem := scalaTestClassesTask.value,
bspScalaMainClassesItem := scalaMainClassesTask.value,
@ -344,6 +369,8 @@ object BuildServerProtocol {
final val Run = "buildTarget/run"
final val CleanCache = "buildTarget/cleanCache"
final val ScalacOptions = "buildTarget/scalacOptions"
final val JvmRunEnvironment = "buildTarget/jvmRunEnvironment"
final val JvmTestEnvironment = "buildTarget/jvmTestEnvironment"
final val ScalaTestClasses = "buildTarget/scalaTestClasses"
final val ScalaMainClasses = "buildTarget/scalaMainClasses"
final val Exit = "build/exit"
@ -443,6 +470,18 @@ object BuildServerProtocol {
val command = Keys.bspBuildTargetScalacOptions.key
val _ = callback.appendExec(s"$command $targets", Some(r.id))
case r if r.method == Method.JvmRunEnvironment =>
val param = Converter.fromJson[JvmRunEnvironmentParams](json(r)).get
val targets = param.targets.map(_.uri).mkString(" ")
val command = Keys.bspBuildTargetJVMRunEnvironment.key
val _ = callback.appendExec(s"$command $targets", Some(r.id))
case r if r.method == Method.JvmTestEnvironment =>
val param = Converter.fromJson[JvmTestEnvironmentParams](json(r)).get
val targets = param.targets.map(_.uri).mkString(" ")
val command = Keys.bspBuildTargetJVMTestEnvironment.key
val _ = callback.appendExec(s"$command $targets", Some(r.id))
case r if r.method == Method.ScalaTestClasses =>
val param = Converter.fromJson[ScalaTestClassesParams](json(r)).get
val targets = param.targets.map(_.uri).mkString(" ")
@ -648,6 +687,33 @@ object BuildServerProtocol {
)
}
private def jvmEnvironmentItem(): Initialize[Task[JvmEnvironmentItem]] = Def.taskDyn {
val target = Keys.bspTargetIdentifier.value
val baseDir = Keys.baseDirectory.value.toURI().toString()
val jvmOptions = Keys.javaOptions.value.toVector
val env = envVars.value
val externalDependencyClasspath = Keys.externalDependencyClasspath.value
val internalDependencyClasspath = for {
(ref, configs) <- bspInternalDependencyConfigurations.value
config <- configs
} yield ref / config / Keys.classDirectory
Def.task {
val classpath =
internalDependencyClasspath.join.value.distinct ++
externalDependencyClasspath.map(_.data)
JvmEnvironmentItem(
target,
classpath.map(_.toURI).toVector,
jvmOptions,
baseDir,
env
)
}
}
private def scalacOptionsTask: Def.Initialize[Task[ScalacOptionsItem]] = Def.taskDyn {
val target = Keys.bspTargetIdentifier.value
val scalacOptions = Keys.scalacOptions.value
@ -878,6 +944,7 @@ object BuildServerProtocol {
}
}
// here
private def scalaMainClassesTask: Initialize[Task[ScalaMainClassesItem]] = Def.task {
val jvmOptions = Keys.javaOptions.value.toVector
val mainClasses = Keys.discoveredMainClasses.value.map(