mirror of https://github.com/sbt/sbt.git
resolve plugin dependency version conflicts according to build order, first part of fix for #329
This commit is contained in:
parent
b0e86898d1
commit
0fbe987cd0
|
|
@ -123,6 +123,12 @@ final class BuildLoader(
|
||||||
full.setRoot(loaders.full),
|
full.setRoot(loaders.full),
|
||||||
loaders.transformAll andThen transformAll
|
loaders.transformAll andThen transformAll
|
||||||
)
|
)
|
||||||
|
def updatePluginManagement(overrides: Set[ModuleID], loader: ClassLoader): BuildLoader =
|
||||||
|
{
|
||||||
|
val mgmt = config.pluginManagement
|
||||||
|
val newConfig = config.copy(pluginManagement = mgmt.copy(overrides = mgmt.overrides ++ overrides, loader = loader))
|
||||||
|
new BuildLoader(fail, state, newConfig, resolvers, builders, transformer, full, transformAll)
|
||||||
|
}
|
||||||
def components = new Components(resolvers.applyFun, builders.applyFun, transformer, full.applyFun, transformAll)
|
def components = new Components(resolvers.applyFun, builders.applyFun, transformer, full.applyFun, transformAll)
|
||||||
def apply(uri: URI): BuildUnit =
|
def apply(uri: URI): BuildUnit =
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,9 @@ object Load
|
||||||
val compilers = Compiler.compilers(ClasspathOptions.boot)(state.configuration, log)
|
val compilers = Compiler.compilers(ClasspathOptions.boot)(state.configuration, log)
|
||||||
val evalPluginDef = EvaluateTask.evalPluginDef(log) _
|
val evalPluginDef = EvaluateTask.evalPluginDef(log) _
|
||||||
val delegates = defaultDelegates
|
val delegates = defaultDelegates
|
||||||
|
val pluginMgmt = PluginManagement(loader)
|
||||||
val inject = InjectSettings(injectGlobal(state), Nil, const(Nil))
|
val inject = InjectSettings(injectGlobal(state), Nil, const(Nil))
|
||||||
new LoadBuildConfiguration(stagingDirectory, classpath, loader, compilers, evalPluginDef, definesClass, delegates, EvaluateTask.injectStreams, inject, None, log)
|
new LoadBuildConfiguration(stagingDirectory, classpath, loader, compilers, evalPluginDef, definesClass, delegates, EvaluateTask.injectStreams, pluginMgmt, inject, None, log)
|
||||||
}
|
}
|
||||||
def injectGlobal(state: State): Seq[Project.Setting[_]] =
|
def injectGlobal(state: State): Seq[Project.Setting[_]] =
|
||||||
(appConfiguration in GlobalScope :== state.configuration) +:
|
(appConfiguration in GlobalScope :== state.configuration) +:
|
||||||
|
|
@ -229,13 +230,14 @@ object Load
|
||||||
if(srcs.isEmpty) const(Nil) else EvaluateConfigurations(eval(), srcs, imports)
|
if(srcs.isEmpty) const(Nil) else EvaluateConfigurations(eval(), srcs, imports)
|
||||||
|
|
||||||
def load(file: File, s: State, config: LoadBuildConfiguration): PartBuild =
|
def load(file: File, s: State, config: LoadBuildConfiguration): PartBuild =
|
||||||
|
load(file, builtinLoader(s, config.copy(pluginManagement = config.pluginManagement.shift) ))
|
||||||
|
def builtinLoader(s: State, config: LoadBuildConfiguration): BuildLoader =
|
||||||
{
|
{
|
||||||
val fail = (uri: URI) => error("Invalid build URI (no handler available): " + uri)
|
val fail = (uri: URI) => error("Invalid build URI (no handler available): " + uri)
|
||||||
val resolver = (info: BuildLoader.ResolveInfo) => RetrieveUnit(info)
|
val resolver = (info: BuildLoader.ResolveInfo) => RetrieveUnit(info)
|
||||||
val build = (info: BuildLoader.BuildInfo) => Some(() => loadUnit(info.uri, info.base, info.state, info.config))
|
val build = (info: BuildLoader.BuildInfo) => Some(() => loadUnit(info.uri, info.base, info.state, info.config))
|
||||||
val components = BuildLoader.components(resolver, build, full = BuildLoader.componentLoader)
|
val components = BuildLoader.components(resolver, build, full = BuildLoader.componentLoader)
|
||||||
val builtinLoader = BuildLoader(components, fail, s, config)
|
BuildLoader(components, fail, s, config)
|
||||||
load(file, builtinLoader)
|
|
||||||
}
|
}
|
||||||
def load(file: File, loaders: BuildLoader): PartBuild = loadURI(IO.directoryURI(file), loaders)
|
def load(file: File, loaders: BuildLoader): PartBuild = loadURI(IO.directoryURI(file), loaders)
|
||||||
def loadURI(uri: URI, loaders: BuildLoader): PartBuild =
|
def loadURI(uri: URI, loaders: BuildLoader): PartBuild =
|
||||||
|
|
@ -246,6 +248,11 @@ object Load
|
||||||
val build = new PartBuild(uri, map)
|
val build = new PartBuild(uri, map)
|
||||||
newLoaders transformAll build
|
newLoaders transformAll build
|
||||||
}
|
}
|
||||||
|
def addOverrides(unit: BuildUnit, loaders: BuildLoader): BuildLoader =
|
||||||
|
{
|
||||||
|
val overrides = PluginManagement.extractOverrides(unit.plugins.fullClasspath)
|
||||||
|
loaders.updatePluginManagement(overrides, unit.plugins.loader)
|
||||||
|
}
|
||||||
def addResolvers(unit: BuildUnit, isRoot: Boolean, loaders: BuildLoader): BuildLoader =
|
def addResolvers(unit: BuildUnit, isRoot: Boolean, loaders: BuildLoader): BuildLoader =
|
||||||
unit.definitions.builds.flatMap(_.buildLoaders) match
|
unit.definitions.builds.flatMap(_.buildLoaders) match
|
||||||
{
|
{
|
||||||
|
|
@ -287,7 +294,7 @@ object Load
|
||||||
{
|
{
|
||||||
val (loadedBuild, refs) = loaded(loaders(b))
|
val (loadedBuild, refs) = loaded(loaders(b))
|
||||||
checkBuildBase(loadedBuild.unit.localBase)
|
checkBuildBase(loadedBuild.unit.localBase)
|
||||||
val newLoader = addResolvers(loadedBuild.unit, builds.isEmpty, loaders)
|
val newLoader = addOverrides(loadedBuild.unit, addResolvers(loadedBuild.unit, builds.isEmpty, loaders))
|
||||||
loadAll(refs.flatMap(Reference.uri) reverse_::: bs, references.updated(b, refs), newLoader, builds.updated(b, loadedBuild))
|
loadAll(refs.flatMap(Reference.uri) reverse_::: bs, references.updated(b, refs), newLoader, builds.updated(b, loadedBuild))
|
||||||
}
|
}
|
||||||
case Nil => (references, builds, loaders)
|
case Nil => (references, builds, loaders)
|
||||||
|
|
@ -428,7 +435,10 @@ object Load
|
||||||
Keys.onLoadMessage <<= Keys.baseDirectory("Loading project definition from " + _)
|
Keys.onLoadMessage <<= Keys.baseDirectory("Loading project definition from " + _)
|
||||||
))
|
))
|
||||||
def enableSbtPlugin(config: LoadBuildConfiguration): LoadBuildConfiguration =
|
def enableSbtPlugin(config: LoadBuildConfiguration): LoadBuildConfiguration =
|
||||||
config.copy(injectSettings = config.injectSettings.copy(global = autoPluginSettings ++ config.injectSettings.global))
|
config.copy(injectSettings = config.injectSettings.copy(
|
||||||
|
global = autoPluginSettings ++ config.injectSettings.global,
|
||||||
|
project = config.pluginManagement.inject ++ config.injectSettings.project
|
||||||
|
))
|
||||||
def activateGlobalPlugin(config: LoadBuildConfiguration): LoadBuildConfiguration =
|
def activateGlobalPlugin(config: LoadBuildConfiguration): LoadBuildConfiguration =
|
||||||
config.globalPlugin match
|
config.globalPlugin match
|
||||||
{
|
{
|
||||||
|
|
@ -624,7 +634,10 @@ object Load
|
||||||
val aggregates = Aggregation.relation(units)
|
val aggregates = Aggregation.relation(units)
|
||||||
new BuildUtil(keyIndex, data, root, Load getRootProject units, getp, configs, aggregates)
|
new BuildUtil(keyIndex, data, root, Load getRootProject units, getp, configs, aggregates)
|
||||||
}
|
}
|
||||||
final case class LoadBuildConfiguration(stagingDirectory: File, classpath: Seq[Attributed[File]], loader: ClassLoader, compilers: Compilers, evalPluginDef: (BuildStructure, State) => Seq[Attributed[File]], definesClass: DefinesClass, delegates: LoadedBuild => Scope => Seq[Scope], scopeLocal: ScopeLocal, injectSettings: InjectSettings, globalPlugin: Option[GlobalPlugin], log: Logger)
|
final case class LoadBuildConfiguration(stagingDirectory: File, classpath: Seq[Attributed[File]], loader: ClassLoader,
|
||||||
|
compilers: Compilers, evalPluginDef: (BuildStructure, State) => Seq[Attributed[File]], definesClass: DefinesClass,
|
||||||
|
delegates: LoadedBuild => Scope => Seq[Scope], scopeLocal: ScopeLocal,
|
||||||
|
pluginManagement: PluginManagement, injectSettings: InjectSettings, globalPlugin: Option[GlobalPlugin], log: Logger)
|
||||||
{
|
{
|
||||||
lazy val (globalPluginClasspath, globalPluginLoader) = pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
|
lazy val (globalPluginClasspath, globalPluginLoader) = pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
|
||||||
lazy val globalPluginNames = if(globalPluginClasspath.isEmpty) Nil else getPluginNames(globalPluginClasspath, globalPluginLoader)
|
lazy val globalPluginNames = if(globalPluginClasspath.isEmpty) Nil else getPluginNames(globalPluginClasspath, globalPluginLoader)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import Keys.Classpath
|
||||||
|
import Project.Setting
|
||||||
|
|
||||||
|
final case class PluginManagement(overrides: Set[ModuleID], applyOverrides: Set[ModuleID], loader: ClassLoader, initialLoader: ClassLoader)
|
||||||
|
{
|
||||||
|
def shift: PluginManagement =
|
||||||
|
PluginManagement(Set.empty, overrides, initialLoader, initialLoader)
|
||||||
|
|
||||||
|
def addOverrides(os: Set[ModuleID]): PluginManagement =
|
||||||
|
copy(overrides = overrides ++ os)
|
||||||
|
|
||||||
|
def addOverrides(cp: Classpath): PluginManagement =
|
||||||
|
addOverrides(PluginManagement extractOverrides cp)
|
||||||
|
|
||||||
|
def inject: Seq[Setting[_]] = Seq(
|
||||||
|
Keys.dependencyOverrides ++= overrides
|
||||||
|
)
|
||||||
|
}
|
||||||
|
object PluginManagement
|
||||||
|
{
|
||||||
|
def apply(initialLoader: ClassLoader): PluginManagement = PluginManagement(Set.empty, Set.empty, initialLoader, initialLoader)
|
||||||
|
|
||||||
|
def extractOverrides(classpath: Classpath): Set[ModuleID] =
|
||||||
|
classpath flatMap { _.metadata get Keys.moduleID.key map keepOverrideInfo } toSet;
|
||||||
|
|
||||||
|
def keepOverrideInfo(m: ModuleID): ModuleID =
|
||||||
|
ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue