bugfix - apply autoImports for global plugins at global configuration stage

Previously, the autoimports for globally defined plugins were not
imported for global configuration files, although they were imported for
project configuration files.

This patch causes an additional plugin discovery phase to happen during
global config evaluation, so that auto-plugins can be detected and their
imports subsequently included.
This commit is contained in:
Tim Harper 2016-01-18 00:21:26 -07:00
parent 96eadfc3dd
commit 2eda2ebd46
6 changed files with 50 additions and 1 deletions

View File

@ -91,7 +91,10 @@ object Load {
def buildGlobalSettings(base: File, files: Seq[File], config: sbt.LoadBuildConfiguration): ClassLoader => Seq[Setting[_]] =
{
val eval = mkEval(data(config.globalPluginClasspath), base, defaultEvalOptions)
val imports = BuildUtil.baseImports ++ BuildUtil.importAllRoot(config.globalPluginNames)
val imports = BuildUtil.baseImports ++
config.detectedGlobalPlugins.imports
loader => {
val loaded = EvaluateConfigurations(eval, files, imports)(loader)
// TODO - We have a potential leak of config-classes in the global directory right now.
@ -718,10 +721,13 @@ object Load {
loadedPlugins: sbt.LoadedPlugins,
eval: () => Eval,
memoSettings: mutable.Map[File, LoadedSbtFile]): DiscoveredProjects = {
// Default sbt files to read, if needed
lazy val defaultSbtFiles = configurationSources(projectBase)
// Classloader of the build
val loader = loadedPlugins.loader
// How to load an individual file for use later.
// TODO - We should import vals defined in other sbt files here, if we wish to
// share. For now, build.sbt files have their own unique namespace.
@ -730,11 +736,13 @@ object Load {
// How to merge SbtFiles we read into one thing
def merge(ls: Seq[LoadedSbtFile]): LoadedSbtFile = (LoadedSbtFile.empty /: ls) { _ merge _ }
// Loads a given file, or pulls from the cache.
def memoLoadSettingsFile(src: File): LoadedSbtFile = memoSettings.getOrElse(src, {
val lf = loadSettingsFile(src)
memoSettings.put(src, lf.clearProjects) // don't load projects twice
lf
})
// Loads a set of sbt files, sorted by their lexical name (current behavior of sbt).
def loadFiles(fs: Seq[File]): LoadedSbtFile =
merge(fs.sortBy(_.getName).map(memoLoadSettingsFile))
@ -971,6 +979,19 @@ final case class LoadBuildConfiguration(
log: Logger) {
lazy val (globalPluginClasspath, globalPluginLoader) = Load.pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
lazy val globalPluginNames = if (globalPluginClasspath.isEmpty) Nil else Load.getPluginNames(globalPluginClasspath, globalPluginLoader)
private[sbt] lazy val globalPluginDefs = {
val pluginData = globalPlugin match {
case Some(x) => PluginData(x.data.fullClasspath, x.data.internalClasspath, Some(x.data.resolvers), Some(x.data.updateReport), Nil)
case None => PluginData(globalPluginClasspath, Nil, None, None, Nil)
}
val baseDir = globalPlugin match {
case Some(x) => x.base
case _ => stagingDirectory
}
Load.loadPluginDefinition(baseDir, this, pluginData)
}
lazy val detectedGlobalPlugins = globalPluginDefs.detected
}
final class IncompatiblePluginsException(msg: String, cause: Throwable) extends Exception(msg, cause)

View File

@ -11,6 +11,7 @@
[@fkorotkov]: http://github.com/fkorotkov
[@hgiddens]: https://github.com/hgiddens
[@DavidPerezIngeniero]: https://github.com/DavidPerezIngeniero
[@timcharper]: https://github.com/timcharper
[2302]: https://github.com/sbt/sbt/issues/2302
[2303]: https://github.com/sbt/sbt/pull/2303
[1967]: https://github.com/sbt/sbt/issues/1967
@ -62,6 +63,8 @@
[1968]: https://github.com/sbt/sbt/issues/1968
[2264]: https://github.com/sbt/sbt/issues/2264
[2172]: https://github.com/sbt/sbt/pull/2172
[2120]: https://github.com/sbt/sbt/issues/2120
[2399]: https://github.com/sbt/sbt/pull/2399
### Fixes with compatibility implications
@ -109,6 +112,7 @@
- Fixes `JavaErrorParser` to parse non-compile-errors [#2256][2256]/[#2272][2272] by [@Duhemm][@Duhemm]
- Fixes task scheduling performance on large builds by skipping checks in `sbt.Execute`. [#2302][2302]/[#2303][2303] by [@jrudolph][@jrudolph]
- Fixes autoImports for AutoPlugins for global configuration files. [#2120][2120]/[#2399][2399] by [@timcharper][@timcharper]
### Def.settings

View File

@ -1,5 +1,15 @@
package test
import sbt._
object Global {
val x = 3
}
object GlobalAutoPlugin extends AutoPlugin {
object autoImport {
lazy val globalAutoPluginSetting = settingKey[String]("A top level setting declared in a plugin.")
}
}

View File

@ -0,0 +1,7 @@
import sbt._
object GlobalLegacyPlugin extends sbt.Plugin {
import sbt.Keys._
val globalLegacyPluginSetting = SettingKey[String]("A top level setting declared by a legacy plugin")
val useGlobalLegacyPluginSetting = globalLegacyPluginSetting in Global
}

View File

@ -0,0 +1,2 @@
// If the GlobalAutoPlugin.autoImport._ does not get brought in, this will fail:
globalAutoPluginSetting := "bar"

View File

@ -0,0 +1,5 @@
/*
If the GlobalLegacyPlugin 'in' statements do not register and get
brought in to the global scope, this will fail
*/
globalLegacyPluginSetting := "foo"