Fix AutoPlugins declared at top-level

Fixes exception occuring when loading auto plugins, which are declared
as top-level classes
This commit is contained in:
Lukasz Piepiora 2014-05-22 23:30:46 +02:00
parent 14176967d8
commit 75a05dfcbf
5 changed files with 95 additions and 6 deletions

View File

@ -108,16 +108,25 @@ case class DetectedAutoPlugin(val name: String, val value: AutoPlugin, val hasAu
*/
final class DetectedPlugins(val plugins: DetectedModules[Plugin], val autoPlugins: Seq[DetectedAutoPlugin], val builds: DetectedModules[Build]) {
/** Sequence of import expressions for the build definition. This includes the names of the [[Plugin]], [[Build]], and [[AutoImport]] modules, but not the [[AutoPlugin]] modules. */
lazy val imports: Seq[String] = BuildUtil.getImports(plugins.names ++ builds.names ++
(autoPlugins flatMap {
lazy val imports: Seq[String] = BuildUtil.getImports(plugins.names ++ builds.names) ++
BuildUtil.importAllRoot(autoImports(autoPluginAutoImports)) ++
BuildUtil.importAll(autoImports(topLevelAutoPluginAutoImports)) ++
BuildUtil.importNamesRoot(autoPlugins.map(_.name).filter(nonTopLevelPlugin))
private[this] lazy val (autoPluginAutoImports, topLevelAutoPluginAutoImports) =
autoPlugins.flatMap {
case DetectedAutoPlugin(name, ap, hasAutoImport) =>
if (hasAutoImport) Some(name + ".autoImport")
if (hasAutoImport) Some(name)
else None
})) ++
BuildUtil.importNamesRoot(autoPlugins map { _.name })
}.partition(nonTopLevelPlugin)
/** A function to select the right [[AutoPlugin]]s from [[autoPlugins]] for a [[Project]]. */
lazy val deducePlugins: (Plugins, Logger) => Seq[AutoPlugin] = Plugins.deducer(autoPlugins.toList map { _.value })
private[this] def autoImports(pluginNames: Seq[String]) = pluginNames.map(_ + ".autoImport")
private[this] def nonTopLevelPlugin(name: String) = name.contains('.')
}
/**

View File

@ -15,6 +15,16 @@ lazy val projE = project.enablePlugins(S)
lazy val projF = project
// with X enabled, TopA is loaded automatically
lazy val projG = project.enablePlugins(X)
// only TopB should be enabled
lazy val projH = project.enablePlugins(TopB)
// enables TopC, which declares topLevelKeyTest
lazy val projI = project.enablePlugins(TopC)
disablePlugins(plugins.IvyPlugin)
check := {
@ -49,10 +59,21 @@ check := {
same(optInValue, " Q S R", "del in projE in q")
val overrideOrgValue = (organization in projE).value
same(overrideOrgValue, "S", "organization in projE")
// tests for top level plugins
val topLevelAValueG = (topLevelDemo in projG).value
same(topLevelAValueG, "TopA: topLevelDemo project projG", "topLevelDemo in projG")
val demoValueG = (demo in projG).value
same(demoValueG, "TopA: demo project projG", "demo in projG")
val topLevelBValueH = (topLevelDemo in projH).value
same(topLevelBValueH, "TopB: topLevelDemo project projH", "topLevelDemo in projH")
val hdel = (del in projH).?.value
same(hdel, None, "del in projH")
}
keyTest := "foo"
topLevelKeyTest := "bar"
def same[T](actual: T, expected: T, label: String) {
assert(actual == expected, s"Expected '$expected' for `$label`, got '$actual'")
}

View File

@ -0,0 +1,47 @@
// no package
// plugins declared within no package should be visible to other plugins in the _root_ package
import sbt._
import sbt.Keys._
object TopLevelImports {
lazy val topLevelDemo = settingKey[String]("A top level demo setting.")
}
object TopA extends AutoPlugin {
import TopLevelImports._
import sbttest.Imports._
val autoImport = TopLevelImports
override def requires = sbttest.X
override def trigger = AllRequirements
override def projectSettings: scala.Seq[sbt.Setting[_]] = Seq(
topLevelDemo := s"TopA: topLevelDemo project ${name.value}",
demo := s"TopA: demo project ${name.value}"
)
}
object TopB extends AutoPlugin {
import TopLevelImports._
val autoImport = TopLevelImports
override def projectSettings: Seq[Setting[_]] = Seq(
topLevelDemo := s"TopB: topLevelDemo project ${name.value}"
)
}
object TopC extends AutoPlugin {
object autoImport {
lazy val topLevelKeyTest = settingKey[String]("A top level setting declared in a plugin.")
}
}

View File

@ -0,0 +1,11 @@
// no package declaration
import sbt._
object D extends AutoPlugin {
object autoImport {
lazy val dKey = settingKey[String]("Test key")
}
}

View File

@ -1,12 +1,13 @@
# First we define the plugin project and publish it
$ copy-file changes/define/build.sbt build.sbt
$ copy-file changes/define/A.scala A.scala
$ copy-file changes/define/D.scala D.scala
# reload implied
> publishLocal
# Now we remove the source code and define a project which uses the build.
$ delete build.sbt A.scala
$ delete build.sbt A.scala D.scala
$ copy-file changes/use/plugins.sbt project/plugins.sbt
> reload
> check