mirror of https://github.com/sbt/sbt.git
Merge pull request #1352 from dansanduleac/issues/1084
Don't inject global plugins' classpath into that of builds, and autotrigger build.update if GP.updated
This commit is contained in:
commit
c5d0c4cd29
|
|
@ -301,7 +301,8 @@ object Defaults extends BuildCommon {
|
||||||
import ScopeFilter.Make.{ inDependencies => inDeps, _ }
|
import ScopeFilter.Make.{ inDependencies => inDeps, _ }
|
||||||
val selectDeps = ScopeFilter(inDeps(ThisProject, includeRoot = false))
|
val selectDeps = ScopeFilter(inDeps(ThisProject, includeRoot = false))
|
||||||
val allUpdates = update.?.all(selectDeps)
|
val allUpdates = update.?.all(selectDeps)
|
||||||
Def.task { allUpdates.value.flatten }
|
// If I am a "build" (a project inside project/) then I have a globalPluginUpdate.
|
||||||
|
Def.task { allUpdates.value.flatten ++ globalPluginUpdate.?.value }
|
||||||
}
|
}
|
||||||
|
|
||||||
def watchSetting: Initialize[Watched] = (pollInterval, thisProjectRef, watchingMessage, triggeredMessage) { (interval, base, msg, trigMsg) =>
|
def watchSetting: Initialize[Watched] = (pollInterval, thisProjectRef, watchingMessage, triggeredMessage) { (interval, base, msg, trigMsg) =>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ object GlobalPlugin {
|
||||||
projectDescriptors ~= { _ ++ gp.descriptors },
|
projectDescriptors ~= { _ ++ gp.descriptors },
|
||||||
projectDependencies ++= gp.projectID +: gp.dependencies,
|
projectDependencies ++= gp.projectID +: gp.dependencies,
|
||||||
resolvers <<= resolvers { rs => (rs ++ gp.resolvers).distinct },
|
resolvers <<= resolvers { rs => (rs ++ gp.resolvers).distinct },
|
||||||
|
globalPluginUpdate := gp.updateReport,
|
||||||
// TODO: these shouldn't be required (but are): the project* settings above should take care of this
|
// TODO: these shouldn't be required (but are): the project* settings above should take care of this
|
||||||
injectInternalClasspath(Runtime, gp.internalClasspath),
|
injectInternalClasspath(Runtime, gp.internalClasspath),
|
||||||
injectInternalClasspath(Compile, gp.internalClasspath)
|
injectInternalClasspath(Compile, gp.internalClasspath)
|
||||||
|
|
@ -44,10 +45,16 @@ object GlobalPlugin {
|
||||||
{
|
{
|
||||||
import structure.{ data, root, rootProject }
|
import structure.{ data, root, rootProject }
|
||||||
val p: Scope = Scope.GlobalScope in ProjectRef(root, rootProject(root))
|
val p: Scope = Scope.GlobalScope in ProjectRef(root, rootProject(root))
|
||||||
val taskInit = (projectID, projectDependencies, projectDescriptors, resolvers, fullClasspath in Runtime, internalDependencyClasspath in Runtime, exportedProducts in Runtime, ivyModule) map {
|
|
||||||
(pid, pdeps, pdescs, rs, cp, intcp, prods, mod) =>
|
val taskInit = Def.task {
|
||||||
val depMap = pdescs + mod.dependencyMapping(state.log)
|
val intcp = (internalDependencyClasspath in Runtime).value
|
||||||
GlobalPluginData(pid, pdeps, depMap, rs, cp, (prods ++ intcp).distinct)
|
val prods = (exportedProducts in Runtime).value
|
||||||
|
val depMap = projectDescriptors.value + ivyModule.value.dependencyMapping(state.log)
|
||||||
|
// If we reference it directly (if it's an executionRoot) then it forces an update, which is not what we want.
|
||||||
|
val updateReport = Def.taskDyn { Def.task { update.value } }.value
|
||||||
|
|
||||||
|
GlobalPluginData(projectID.value, projectDependencies.value, depMap, resolvers.value, (fullClasspath in Runtime).value,
|
||||||
|
(prods ++ intcp).distinct)(updateReport)
|
||||||
}
|
}
|
||||||
val resolvedTaskInit = taskInit mapReferenced Project.mapScope(Scope replaceThis p)
|
val resolvedTaskInit = taskInit mapReferenced Project.mapScope(Scope replaceThis p)
|
||||||
val task = resolvedTaskInit evaluate data
|
val task = resolvedTaskInit evaluate data
|
||||||
|
|
@ -72,5 +79,5 @@ object GlobalPlugin {
|
||||||
version := "0.0"
|
version := "0.0"
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
final case class GlobalPluginData(projectID: ModuleID, dependencies: Seq[ModuleID], descriptors: Map[ModuleRevisionId, ModuleDescriptor], resolvers: Seq[Resolver], fullClasspath: Classpath, internalClasspath: Classpath)
|
final case class GlobalPluginData(projectID: ModuleID, dependencies: Seq[ModuleID], descriptors: Map[ModuleRevisionId, ModuleDescriptor], resolvers: Seq[Resolver], fullClasspath: Classpath, internalClasspath: Classpath)(val updateReport: UpdateReport)
|
||||||
final case class GlobalPlugin(data: GlobalPluginData, structure: BuildStructure, inject: Seq[Setting[_]], base: File)
|
final case class GlobalPlugin(data: GlobalPluginData, structure: BuildStructure, inject: Seq[Setting[_]], base: File)
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,7 @@ object Keys {
|
||||||
val stateStreams = AttributeKey[Streams]("streams-manager", "Streams manager, which provides streams for different contexts. Setting this on State will override the default Streams implementation.")
|
val stateStreams = AttributeKey[Streams]("streams-manager", "Streams manager, which provides streams for different contexts. Setting this on State will override the default Streams implementation.")
|
||||||
val resolvedScoped = Def.resolvedScoped
|
val resolvedScoped = Def.resolvedScoped
|
||||||
val pluginData = TaskKey[PluginData]("plugin-data", "Information from the plugin build needed in the main build definition.", DTask)
|
val pluginData = TaskKey[PluginData]("plugin-data", "Information from the plugin build needed in the main build definition.", DTask)
|
||||||
|
val globalPluginUpdate = TaskKey[UpdateReport]("global-plugin-update", "A hook to get the UpdateReport of the global plugin.", DTask)
|
||||||
|
|
||||||
// wrapper to work around SI-2915
|
// wrapper to work around SI-2915
|
||||||
private[sbt] final class TaskProgress(val progress: ExecuteProgress[Task])
|
private[sbt] final class TaskProgress(val progress: ExecuteProgress[Task])
|
||||||
|
|
|
||||||
|
|
@ -73,25 +73,17 @@ object Load {
|
||||||
}
|
}
|
||||||
def buildGlobalSettings(base: File, files: Seq[File], config: sbt.LoadBuildConfiguration): ClassLoader => Seq[Setting[_]] =
|
def buildGlobalSettings(base: File, files: Seq[File], config: sbt.LoadBuildConfiguration): ClassLoader => Seq[Setting[_]] =
|
||||||
{
|
{
|
||||||
val eval = mkEval(data(config.classpath), base, defaultEvalOptions)
|
val eval = mkEval(data(config.globalPluginClasspath), base, defaultEvalOptions)
|
||||||
val imports = BuildUtil.baseImports ++ BuildUtil.importAllRoot(config.globalPluginNames)
|
val imports = BuildUtil.baseImports ++ BuildUtil.importAllRoot(config.globalPluginNames)
|
||||||
loader => EvaluateConfigurations(eval, files, imports)(loader).settings
|
loader => EvaluateConfigurations(eval, files, imports)(loader).settings
|
||||||
}
|
}
|
||||||
def loadGlobal(state: State, base: File, global: File, config: sbt.LoadBuildConfiguration): sbt.LoadBuildConfiguration =
|
def loadGlobal(state: State, base: File, global: File, config: sbt.LoadBuildConfiguration): sbt.LoadBuildConfiguration =
|
||||||
if (base != global && global.exists) {
|
if (base != global && global.exists) {
|
||||||
val gp = GlobalPlugin.load(global, state, config)
|
val gp = GlobalPlugin.load(global, state, config)
|
||||||
val pm = setGlobalPluginLoader(gp, config.pluginManagement)
|
config.copy(globalPlugin = Some(gp))
|
||||||
val cp = (gp.data.fullClasspath ++ config.classpath).distinct
|
|
||||||
config.copy(globalPlugin = Some(gp), pluginManagement = pm, classpath = cp)
|
|
||||||
} else
|
} else
|
||||||
config
|
config
|
||||||
|
|
||||||
private[this] def setGlobalPluginLoader(gp: GlobalPlugin, pm: PluginManagement): PluginManagement =
|
|
||||||
{
|
|
||||||
val newLoader = ClasspathUtilities.toLoader(data(gp.data.fullClasspath), pm.initialLoader)
|
|
||||||
pm.copy(initialLoader = newLoader)
|
|
||||||
}
|
|
||||||
|
|
||||||
def defaultDelegates: sbt.LoadedBuild => Scope => Seq[Scope] = (lb: sbt.LoadedBuild) => {
|
def defaultDelegates: sbt.LoadedBuild => Scope => Seq[Scope] = (lb: sbt.LoadedBuild) => {
|
||||||
val rootProject = getRootProject(lb.units)
|
val rootProject = getRootProject(lb.units)
|
||||||
def resolveRef(project: Reference): ResolvedReference = Scope.resolveReference(lb.root, rootProject, project)
|
def resolveRef(project: Reference): ResolvedReference = Scope.resolveReference(lb.root, rootProject, project)
|
||||||
|
|
@ -688,7 +680,6 @@ object Load {
|
||||||
DiscoveredProjects(root.headOption, nonRoot, rawFiles)
|
DiscoveredProjects(root.headOption, nonRoot, rawFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
@deprecated("No longer used.", "0.13.0")
|
|
||||||
def globalPluginClasspath(globalPlugin: Option[GlobalPlugin]): Seq[Attributed[File]] =
|
def globalPluginClasspath(globalPlugin: Option[GlobalPlugin]): Seq[Attributed[File]] =
|
||||||
globalPlugin match {
|
globalPlugin match {
|
||||||
case Some(cp) => cp.data.fullClasspath
|
case Some(cp) => cp.data.fullClasspath
|
||||||
|
|
@ -733,7 +724,7 @@ object Load {
|
||||||
!(dir * -GlobFilter(DefaultTargetName)).get.isEmpty
|
!(dir * -GlobFilter(DefaultTargetName)).get.isEmpty
|
||||||
}
|
}
|
||||||
def noPlugins(dir: File, config: sbt.LoadBuildConfiguration): sbt.LoadedPlugins =
|
def noPlugins(dir: File, config: sbt.LoadBuildConfiguration): sbt.LoadedPlugins =
|
||||||
loadPluginDefinition(dir, config, PluginData(config.classpath, None, None))
|
loadPluginDefinition(dir, config, PluginData(config.globalPluginClasspath, None, None))
|
||||||
def buildPlugins(dir: File, s: State, config: sbt.LoadBuildConfiguration): sbt.LoadedPlugins =
|
def buildPlugins(dir: File, s: State, config: sbt.LoadBuildConfiguration): sbt.LoadedPlugins =
|
||||||
loadPluginDefinition(dir, config, buildPluginDefinition(dir, s, config))
|
loadPluginDefinition(dir, config, buildPluginDefinition(dir, s, config))
|
||||||
|
|
||||||
|
|
@ -903,11 +894,8 @@ final case class LoadBuildConfiguration(
|
||||||
globalPlugin: Option[GlobalPlugin],
|
globalPlugin: Option[GlobalPlugin],
|
||||||
extraBuilds: Seq[URI],
|
extraBuilds: Seq[URI],
|
||||||
log: Logger) {
|
log: Logger) {
|
||||||
@deprecated("Use `classpath`.", "0.13.0")
|
lazy val (globalPluginClasspath, globalPluginLoader) = Load.pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
|
||||||
lazy val globalPluginClasspath = classpath
|
lazy val globalPluginNames = if (globalPluginClasspath.isEmpty) Nil else Load.getPluginNames(globalPluginClasspath, globalPluginLoader)
|
||||||
@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)
|
final class IncompatiblePluginsException(msg: String, cause: Throwable) extends Exception(msg, cause)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# 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
|
|
||||||
|
|
@ -10,11 +10,11 @@ object MyBuild extends Build {
|
||||||
|
|
||||||
lazy val proj = Project("my-test-proj", file("."), settings = mySettings)
|
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)")
|
lazy val check = taskKey[Unit]("Verifies that the junit dependency has the newer version (4.8)")
|
||||||
|
|
||||||
def checkVersion(report: UpdateReport) {
|
def checkVersion(report: UpdateReport) {
|
||||||
for(mod <- report.allModules) {
|
for(mod <- report.allModules) {
|
||||||
if(mod.name == "junit") assert(mod.revision == "4.5", s"JUnit version (${mod.revision}) was not overridden")
|
if(mod.name == "junit") assert(mod.revision == "4.8", s"JUnit version (${mod.revision}) does not have the correct version")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
// use a small java library instead of a plugin to avoid incompatibilities when upgrading
|
// 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
|
// This version should be overridden by the one in the project.
|
||||||
libraryDependencies += "junit" % "junit" % "4.5"
|
libraryDependencies += "junit" % "junit" % "4.5"
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
// the version should be overridden by the global plugin
|
// the version should override the one from the global plugin
|
||||||
libraryDependencies += "junit" % "junit" % "4.8"
|
libraryDependencies += "junit" % "junit" % "4.8"
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ $ copy-file changes/global-plugins.sbt global/plugins/plugins.sbt
|
||||||
# check that it is on the classpath
|
# check that it is on the classpath
|
||||||
> eval (x => ()) : (org.junit.Test => Unit)
|
> eval (x => ()) : (org.junit.Test => Unit)
|
||||||
|
|
||||||
# ensure that the global plugin version overrides the local version
|
# ensure that the global plugin version is overridden by the local version
|
||||||
|
# (because it's older)
|
||||||
$ copy-file changes/plugins.sbt project/plugins.sbt
|
$ copy-file changes/plugins.sbt project/plugins.sbt
|
||||||
> reload
|
> reload
|
||||||
> check
|
> check
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue