mirror of https://github.com/sbt/sbt.git
[2.x] Add a resolvedScalacOptions task that resolves cache placeholders (#9610)
Add a resolvedScalacOptions task that resolves cache placeholders in scalacOptions to absolute machine paths. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8753a98161
commit
3045cd0c46
|
|
@ -1147,6 +1147,9 @@ object Defaults extends BuildCommon with DefExtra {
|
|||
consoleQuick / scalacOptions := Def.uncached {
|
||||
Compiler.toConsoleScalacOptions(scalacOptions.value)
|
||||
},
|
||||
resolvedScalacOptions := Def.uncached {
|
||||
Compiler.resolveVirtualizedScalacOptions(scalacOptions.value, rootPaths.value)
|
||||
},
|
||||
consoleQuick / forkOptions := Def.uncached((console / forkOptions).value),
|
||||
discoveredMainClasses := compile
|
||||
.map(discoverMainClasses)
|
||||
|
|
|
|||
|
|
@ -217,6 +217,8 @@ object Keys {
|
|||
val autoCompilerPlugins = settingKey[Boolean]("If true, enables automatically generating -Xplugin arguments to the compiler based on the classpath for the " + CompilerPlugin.name + " configuration.").withRank(AMinusSetting)
|
||||
val maxErrors = settingKey[Int]("The maximum number of errors, such as compile errors, to list.").withRank(ASetting)
|
||||
val scalacOptions = taskKey[Seq[String]]("Options for the Scala compiler.").withRank(BPlusTask)
|
||||
@transient
|
||||
val resolvedScalacOptions = taskKey[Seq[String]]("scalacOptions with cache placeholders (e.g. ${CSR_CACHE}) resolved to absolute machine paths.").withRank(BPlusTask)
|
||||
val javacOptions = taskKey[Seq[String]]("Options for the Java compiler.").withRank(BPlusTask)
|
||||
val incOptions = taskKey[IncOptions]("Options for the incremental compiler.").withRank(BTask)
|
||||
val extraIncOptions = taskKey[Seq[(String, String)]]("Extra options for the incremental compiler").withRank(CTask)
|
||||
|
|
@ -509,6 +511,7 @@ object Keys {
|
|||
val bspBuildTargetRun = inputKey[Unit]("Corresponds to buildTarget/run request").withRank(DTask)
|
||||
val bspBuildTargetCleanCache = inputKey[Unit]("Corresponds to buildTarget/cleanCache request").withRank(DTask)
|
||||
val bspBuildTargetScalacOptions = inputKey[Unit]("").withRank(DTask)
|
||||
@transient
|
||||
val bspBuildTargetScalacOptionsItem = taskKey[ScalacOptionsItem]("").withRank(DTask)
|
||||
val bspBuildTargetJavacOptions = inputKey[Unit]("Implementation of buildTarget/javacOptions").withRank(DTask)
|
||||
val bspBuildTargetJavacOptionsItem = taskKey[JavacOptionsItem]("Item of buildTarget/javacOptions").withRank(DTask)
|
||||
|
|
|
|||
|
|
@ -219,9 +219,11 @@ object BuildServerProtocol {
|
|||
val items = bspBuildTargetScalacOptionsItem.result.all(filter).value
|
||||
val appProvider = appConfiguration.value.provider()
|
||||
val sbtJars = appProvider.mainClasspath()
|
||||
val rootPaths = Keys.rootPaths.value
|
||||
val buildItems = workspace.builds.map { build =>
|
||||
val plugins: LoadedPlugins = build._2.unit.plugins
|
||||
val scalacOptions = plugins.pluginData.scalacOptions
|
||||
val scalacOptions =
|
||||
Compiler.resolveVirtualizedScalacOptions(plugins.pluginData.scalacOptions, rootPaths)
|
||||
val pluginClasspath = plugins.classpath
|
||||
val converter = plugins.pluginData.converter
|
||||
val classpath =
|
||||
|
|
@ -330,7 +332,7 @@ object BuildServerProtocol {
|
|||
bspBuildTargetRun := bspRunTask.evaluated,
|
||||
bspBuildTargetScalacOptionsItem := {
|
||||
val target = Keys.bspTargetIdentifier.value
|
||||
val scalacOptions = Keys.scalacOptions.value.toVector
|
||||
val scalacOptions = Keys.resolvedScalacOptions.value.toVector
|
||||
val classDirectory = Keys.classDirectory.value
|
||||
val classpath = classpathTask.value
|
||||
ScalacOptionsItem(target, scalacOptions, classpath, classDirectory.toURI)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
val check = taskKey[Unit]("Verify resolvedScalacOptions resolves cache placeholders (#9578).")
|
||||
|
||||
scalaVersion := "2.13.16"
|
||||
|
||||
addCompilerPlugin(("org.typelevel" % "kind-projector" % "0.13.3").cross(CrossVersion.full))
|
||||
|
||||
check := Def.uncached {
|
||||
val raw = (Compile / scalacOptions).value
|
||||
val resolved = (Compile / resolvedScalacOptions).value
|
||||
|
||||
assert(
|
||||
raw.exists(_.contains("${CSR_CACHE}")),
|
||||
s"expected a virtualized coursier-cache placeholder in raw scalacOptions, got: $raw"
|
||||
)
|
||||
assert(
|
||||
resolved.forall(!_.contains("${")),
|
||||
s"resolvedScalacOptions still contains a cache placeholder: $resolved"
|
||||
)
|
||||
|
||||
val pluginArg = resolved
|
||||
.find(_.startsWith("-Xplugin:"))
|
||||
.getOrElse(sys.error(s"no -Xplugin entry in resolvedScalacOptions: $resolved"))
|
||||
val jar = new java.io.File(pluginArg.stripPrefix("-Xplugin:"))
|
||||
assert(jar.isAbsolute, s"resolved -Xplugin path is not absolute: $jar")
|
||||
assert(jar.exists, s"resolved -Xplugin jar does not exist: $jar")
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# resolvedScalacOptions must resolve ${CSR_CACHE} placeholders to absolute machine paths (#9578)
|
||||
> check
|
||||
|
|
@ -38,6 +38,12 @@ lazy val util = project.settings(
|
|||
Compile / classDirectory := baseDirectory.value / "classes"
|
||||
)
|
||||
|
||||
lazy val scalacOptionsPlugin = project
|
||||
.in(file("scalac-options-plugin"))
|
||||
.settings(
|
||||
addCompilerPlugin(("org.typelevel" % "kind-projector" % "0.13.3").cross(CrossVersion.full))
|
||||
)
|
||||
|
||||
lazy val diagnostics = project
|
||||
|
||||
lazy val javaProj = project
|
||||
|
|
|
|||
|
|
@ -432,6 +432,39 @@ class BuildServerTest extends AbstractServerTest {
|
|||
)
|
||||
}
|
||||
|
||||
test("buildTarget/scalacOptions resolves cache placeholders (#9578)") {
|
||||
val buildTargets = Seq(buildTargetUri("scalacOptionsPlugin", "Compile"))
|
||||
val id = scalacOptions(buildTargets)
|
||||
val result =
|
||||
svr.session.waitForResultInResponseMsg[ScalacOptionsResult](30.seconds, id).get
|
||||
val options = result.items.head.options
|
||||
|
||||
assert(
|
||||
options.forall(!_.contains("${")),
|
||||
s"buildTarget/scalacOptions returned an unresolved cache placeholder: $options"
|
||||
)
|
||||
|
||||
// The kind-projector compiler plugin must be reported as a concrete, absolute,
|
||||
// existing jar path — not a virtualized ${CSR_CACHE}/... reference.
|
||||
val xplugin = options
|
||||
.find(_.startsWith("-Xplugin:"))
|
||||
.getOrElse(fail(s"expected a -Xplugin compiler-plugin option, got: $options"))
|
||||
val pluginPath = xplugin.stripPrefix("-Xplugin:")
|
||||
val pluginFile = new File(pluginPath)
|
||||
assert(
|
||||
pluginFile.isAbsolute,
|
||||
s"resolved -Xplugin path is not absolute: $pluginPath"
|
||||
)
|
||||
assert(
|
||||
pluginFile.getName.startsWith("kind-projector"),
|
||||
s"expected the kind-projector plugin jar, got: $pluginPath"
|
||||
)
|
||||
assert(
|
||||
pluginFile.exists,
|
||||
s"resolved -Xplugin jar does not exist on disk: $pluginPath"
|
||||
)
|
||||
}
|
||||
|
||||
test("buildTarget/cleanCache") {
|
||||
def classFile = svr.baseDirectory.toPath.resolve(
|
||||
"target/out/jvm/scala-2.13.11/runandtest/classes/main/Main.class"
|
||||
|
|
|
|||
Loading…
Reference in New Issue