[2.x] fix: Fixes global plugin loading (#9391)

**Problem**
Global plugin loading doesn't work.

**Solution**
1. Use ModuleID from to supply the location of global-plugin module.
2. Update pluginData with the global plugin classpath.
This commit is contained in:
eugene yokota
2026-06-28 14:57:18 -04:00
committed by GitHub
parent 3d99cffd5a
commit 0ef972706c
5 changed files with 54 additions and 42 deletions
@@ -9,6 +9,8 @@
package sbt
package internal
import java.io.File
import java.net.URI
import sbt.librarymanagement.{
Configuration,
Configurations,
@@ -23,21 +25,21 @@ import Configurations.{ Compile, Runtime }
import sbt.ProjectExtra.{ extract, runUnloadHooks, setProject }
import sbt.SlashSyntax0.*
import sbt.librarymanagement.LibraryManagementCodec.given
import java.io.File
object GlobalPlugin {
// constructs a sequence of settings that may be appended to a project's settings to
// statically add the global plugin as a classpath dependency.
// static here meaning that the relevant tasks for the global plugin have already been evaluated
def inject(gp: GlobalPluginData): Seq[Setting[?]] =
val gpWithJar = gp.exportedJarUris.headOption
.fold(gp.projectID)(uri => gp.projectID.from(uri.toString))
Seq[Setting[?]](
projectDependencies ++= gp.projectID +: gp.dependencies,
projectDependencies ++= gpWithJar +: gp.dependencies,
resolvers := {
val rs = resolvers.value
(rs ++ gp.resolvers).distinct
},
globalPluginUpdate := gp.updateReport,
// TODO: these shouldn't be required (but are): the project* settings above should take care of this
injectInternalClasspath(Runtime, gp.internalClasspath),
injectInternalClasspath(Compile, gp.internalClasspath)
)
@@ -76,13 +78,16 @@ object GlobalPlugin {
val taskInit = Def.task {
val intcp = (Runtime / internalDependencyClasspath).value
val prods = (Runtime / exportedProducts).value
val converter = fileConverter.value
val exportedJarUris = prods.map(a => converter.toPath(a.data).toUri).toVector
GlobalPluginData(
projectID.value,
projectDependencies.value,
resolvers.value.toVector,
(Runtime / fullClasspath).value,
(prods ++ intcp).distinct
(prods ++ intcp).distinct,
exportedJarUris
)(updateReport.value)
}
val resolvedTaskInit = taskInit.mapReferenced(Project.replaceThis(p))
@@ -120,7 +125,8 @@ final case class GlobalPluginData(
dependencies: Seq[ModuleID],
resolvers: Vector[Resolver],
fullClasspath: Classpath,
internalClasspath: Classpath
internalClasspath: Classpath,
exportedJarUris: Vector[URI],
)(val updateReport: UpdateReport)
final case class GlobalPlugin(
data: GlobalPluginData,
+37 -35
View File
@@ -1411,41 +1411,43 @@ private[sbt] object Load {
case None => Nil
/** These are the settings defined when loading a project "meta" build. */
val autoPluginSettings: Seq[Setting[?]] = inScope(GlobalScope.rescope(LocalRootProject))(
Seq(
sbtPlugin :== true,
isMetaBuild :== true,
pluginData := Def.uncached {
val prod = (Configurations.Runtime / exportedProducts).value
val internalCp = (Configurations.Runtime / internalDependencyClasspath).value
val cp = (Configurations.Runtime / fullClasspath).value
val opts = (Configurations.Compile / scalacOptions).value
val javaOpts = (Configurations.Compile / javacOptions).value
val unmanagedSrcDirs = (Configurations.Compile / unmanagedSourceDirectories).value
val unmanagedSrcs = (Configurations.Compile / unmanagedSources).value
val managedSrcDirs = (Configurations.Compile / managedSourceDirectories).value
val managedSrcs = (Configurations.Compile / managedSources).value
val buildTarget = (Configurations.Compile / bspTargetIdentifier).value
val converter = fileConverter.value
PluginData(
removeEntries(cp, prod),
prod,
Some(fullResolvers.value.toVector),
Some(update.value),
opts,
javaOpts,
unmanagedSrcDirs,
unmanagedSrcs,
managedSrcDirs,
managedSrcs,
Some(buildTarget),
converter,
internalCp,
)
},
onLoadMessage := ("loading project definition from " + baseDirectory.value)
def autoPluginSettings(config: LoadBuildConfiguration): Seq[Setting[?]] =
inScope(GlobalScope.rescope(LocalRootProject))(
Seq(
sbtPlugin :== true,
isMetaBuild :== true,
pluginData := Def.uncached {
val gpClasspath = globalPluginClasspath(config.globalPlugin)
val prod = (Configurations.Runtime / exportedProducts).value
val internalCp = (Configurations.Runtime / internalDependencyClasspath).value
val cp = (Configurations.Runtime / fullClasspath).value
val opts = (Configurations.Compile / scalacOptions).value
val javaOpts = (Configurations.Compile / javacOptions).value
val unmanagedSrcDirs = (Configurations.Compile / unmanagedSourceDirectories).value
val unmanagedSrcs = (Configurations.Compile / unmanagedSources).value
val managedSrcDirs = (Configurations.Compile / managedSourceDirectories).value
val managedSrcs = (Configurations.Compile / managedSources).value
val buildTarget = (Configurations.Compile / bspTargetIdentifier).value
val converter = fileConverter.value
PluginData(
(removeEntries(cp, prod) ++ gpClasspath).distinct,
prod,
Some(fullResolvers.value.toVector),
Some(update.value),
opts,
javaOpts,
unmanagedSrcDirs,
unmanagedSrcs,
managedSrcDirs,
managedSrcs,
Some(buildTarget),
converter,
internalCp,
)
},
onLoadMessage := ("loading project definition from " + baseDirectory.value)
)
)
)
private def removeEntries(
cp: Def.Classpath,
@@ -1459,7 +1461,7 @@ private[sbt] object Load {
def enableSbtPlugin(config: LoadBuildConfiguration): LoadBuildConfiguration =
config.copy(
injectSettings = config.injectSettings.copy(
global = autoPluginSettings ++ config.injectSettings.global,
global = autoPluginSettings(config) ++ config.injectSettings.global,
project = config.pluginManagement.inject ++ config.injectSettings.project
)
)