mirror of https://github.com/sbt/sbt.git
Load global plugins in their own class loader and replace the base loader with that. Fixes #272.
Also, replace the base classpath with the global classpath.
This commit is contained in:
parent
52954b3ae7
commit
8cb7e23011
|
|
@ -74,15 +74,25 @@ object Load
|
|||
}
|
||||
def buildGlobalSettings(base: File, files: Seq[File], config: LoadBuildConfiguration): ClassLoader => Seq[Setting[_]] =
|
||||
{
|
||||
val eval = mkEval(data(config.globalPluginClasspath), base, defaultEvalOptions)
|
||||
val eval = mkEval(data(config.classpath), base, defaultEvalOptions)
|
||||
val imports = baseImports ++ importAllRoot(config.globalPluginNames)
|
||||
loader => EvaluateConfigurations(eval, files, imports)(loader).settings
|
||||
}
|
||||
def loadGlobal(state: State, base: File, global: File, config: LoadBuildConfiguration): LoadBuildConfiguration =
|
||||
if(base != global && global.exists)
|
||||
config.copy(globalPlugin = Some(GlobalPlugin.load(global, state, config)))
|
||||
else
|
||||
if(base != global && global.exists) {
|
||||
val gp = GlobalPlugin.load(global, state, config)
|
||||
val pm = setGlobalPluginLoader(gp, config.pluginManagement)
|
||||
val cp = (gp.data.fullClasspath ++ config.classpath).distinct
|
||||
config.copy(globalPlugin = Some(gp), pluginManagement = pm, classpath = cp)
|
||||
} else
|
||||
config
|
||||
|
||||
private[this] def setGlobalPluginLoader(gp: GlobalPlugin, pm: PluginManagement): PluginManagement =
|
||||
{
|
||||
val newLoader = ClasspathUtilities.toLoader(Build.data(gp.data.fullClasspath), pm.initialLoader)
|
||||
pm.copy(initialLoader = newLoader)
|
||||
}
|
||||
|
||||
def defaultDelegates: LoadedBuild => Scope => Seq[Scope] = (lb: LoadedBuild) => {
|
||||
val rootProject = getRootProject(lb.units)
|
||||
def resolveRef(project: Reference): ResolvedReference = Scope.resolveReference(lb.root, rootProject, project)
|
||||
|
|
@ -441,6 +451,7 @@ object Load
|
|||
expand(auto)
|
||||
}
|
||||
|
||||
@deprecated("No longer used.", "0.13.0")
|
||||
def globalPluginClasspath(globalPlugin: Option[GlobalPlugin]): Seq[Attributed[File]] =
|
||||
globalPlugin match
|
||||
{
|
||||
|
|
@ -483,7 +494,7 @@ object Load
|
|||
!(dir * -GlobFilter(DefaultTargetName)).get.isEmpty
|
||||
}
|
||||
def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins =
|
||||
loadPluginDefinition(dir, config, PluginData(config.globalPluginClasspath, None, None))
|
||||
loadPluginDefinition(dir, config, PluginData(config.classpath, None, None))
|
||||
def buildPlugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins =
|
||||
loadPluginDefinition(dir, config, buildPluginDefinition(dir, s, config))
|
||||
|
||||
|
|
@ -661,8 +672,11 @@ final case class LoadBuildConfiguration(stagingDirectory: File, classpath: Seq[A
|
|||
pluginManagement: PluginManagement, injectSettings: Load.InjectSettings, globalPlugin: Option[GlobalPlugin], extraBuilds: Seq[URI],
|
||||
log: Logger)
|
||||
{
|
||||
lazy val (globalPluginClasspath, globalPluginLoader) = Load.pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
|
||||
lazy val globalPluginNames = if(globalPluginClasspath.isEmpty) Nil else Load.getPluginNames(globalPluginClasspath, globalPluginLoader)
|
||||
@deprecated("Use `classpath`.", "0.13.0")
|
||||
lazy val globalPluginClasspath = classpath
|
||||
@deprecated("Use `pluginManagement.initialLoader`.", "0.13.0")
|
||||
lazy val globalPluginLoader = pluginManagement.initialLoader
|
||||
lazy val globalPluginNames = if(classpath.isEmpty) Nil else Load.getPluginNames(classpath, pluginManagement.initialLoader)
|
||||
}
|
||||
|
||||
final class IncompatiblePluginsException(msg: String, cause: Throwable) extends Exception(msg, cause)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
# tests that a source file in $sbt.global.base/plugins/ is available to the build definition in project/
|
||||
|
||||
# dummy to ensure project gets loaded
|
||||
> name
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import sbt._
|
||||
import sbt.Keys._
|
||||
|
||||
object MyBuild extends Build {
|
||||
lazy val mySettings = Defaults.defaultSettings ++ Seq(
|
||||
name := "my-test-proj",
|
||||
organization := "com.example",
|
||||
check <<= update map checkVersion,
|
||||
version := "0.1.0-SNAPSHOT")
|
||||
|
||||
lazy val proj = Project("my-test-proj", file("."), settings = mySettings)
|
||||
|
||||
lazy val check = taskKey[Unit]("Verifies that the junit dependency has the older version (4.5)")
|
||||
|
||||
def checkVersion(report: UpdateReport) {
|
||||
for(mod <- report.allModules) {
|
||||
if(mod.name == "junit") assert(mod.revision == "4.5", s"JUnit version (${mod.revision}) was not overridden")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
// use a small java library instead of a plugin to avoid incompatibilities when upgrading
|
||||
// use an old version to check that it will override a newer version in a build definition
|
||||
libraryDependencies += "junit" % "junit" % "4.5"
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// the version should be overridden by the global plugin
|
||||
libraryDependencies += "junit" % "junit" % "4.8"
|
||||
|
|
@ -1,4 +1,17 @@
|
|||
# tests that a source file in $sbt.global.base/plugins/ is available to the build definition in project/
|
||||
$ copy-file changes/Build.scala project/Build.scala
|
||||
> reload
|
||||
|
||||
# dummy to ensure project gets loaded
|
||||
> name
|
||||
# ensure that a new global dependency gets picked up
|
||||
$ copy-file changes/global-plugins.sbt global/plugins/plugins.sbt
|
||||
> reload
|
||||
|
||||
# check that the class can be loaded
|
||||
> eval Class.forName("org.junit.Test")
|
||||
|
||||
# check that it is on the classpath
|
||||
> eval (x => ()) : (org.junit.Test => Unit)
|
||||
|
||||
# ensure that the global plugin version overrides the local version
|
||||
$ copy-file changes/plugins.sbt project/plugins.sbt
|
||||
> reload
|
||||
> check
|
||||
|
|
|
|||
Loading…
Reference in New Issue