mirror of https://github.com/sbt/sbt.git
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:
parent
14176967d8
commit
75a05dfcbf
|
|
@ -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('.')
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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'")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// no package declaration
|
||||
|
||||
import sbt._
|
||||
|
||||
object D extends AutoPlugin {
|
||||
|
||||
object autoImport {
|
||||
lazy val dKey = settingKey[String]("Test key")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue