diff --git a/main/Defaults.scala b/main/Defaults.scala index c45eb3605..5374226ff 100755 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -874,8 +874,9 @@ object Classpaths def sbtClassifiersTasks = inTask(updateSbtClassifiers)(Seq( transitiveClassifiers in GlobalScope in updateSbtClassifiers ~= ( _.filter(_ != DocClassifier) ), - externalResolvers <<= (externalResolvers, appConfiguration) map { (defaultRs, ac) => - bootRepositories(ac) getOrElse defaultRs + externalResolvers <<= (externalResolvers, appConfiguration, buildStructure, thisProjectRef) map { (defaultRs, ac, struct, ref) => + val explicit = struct.units(ref.build).unit.plugins.pluginData.resolvers + explicit orElse bootRepositories(ac) getOrElse defaultRs }, ivyConfiguration <<= (externalResolvers, ivyPaths, offline, checksums, appConfiguration, streams) map { (rs, paths, off, check, app, s) => new InlineIvyConfiguration(paths, rs, Nil, Nil, off, Option(lock(app)), check, s.log) @@ -888,7 +889,8 @@ object Classpaths updateSbtClassifiers in TaskGlobal <<= (ivySbt, classifiersModule, updateConfiguration, ivyScala, target in LocalRootProject, appConfiguration, streams) map { (is, mod, c, ivyScala, out, app, s) => withExcludes(out, mod.classifiers, lock(app)) { excludes => - IvyActions.transitiveScratch(is, "sbt", GetClassifiersConfiguration(mod, excludes, c, ivyScala), s.log) + val noExplicitCheck = ivyScala.map(_.copy(checkExplicit=false)) + IvyActions.transitiveScratch(is, "sbt", GetClassifiersConfiguration(mod, excludes, c, noExplicitCheck), s.log) } } tag(Tags.Update, Tags.Network) )) diff --git a/main/EvaluateTask.scala b/main/EvaluateTask.scala index b5fb1e99a..a1fdfd4b8 100644 --- a/main/EvaluateTask.scala +++ b/main/EvaluateTask.scala @@ -6,12 +6,13 @@ package sbt import java.io.File import Project.{ScopedKey, Setting} import Keys.{streams, Streams, TaskStreams} - import Keys.{dummyRoots, dummyState, dummyStreamsManager, executionRoots, streamsManager, taskDefinitionKey, transformState} + import Keys.{dummyRoots, dummyState, dummyStreamsManager, executionRoots, pluginData, streamsManager, taskDefinitionKey, transformState} import Scope.{GlobalScope, ThisScope} import Types.const import scala.Console.{RED, RESET} final case class EvaluateConfig(cancelable: Boolean, restrictions: Seq[Tags.Rule], checkCycles: Boolean = false) +final case class PluginData(classpath: Seq[Attributed[File]], resolvers: Option[Seq[Resolver]]) object EvaluateTask { import Load.BuildStructure @@ -60,13 +61,13 @@ object EvaluateTask (executionRoots in GlobalScope) ::= dummyRoots ) - def evalPluginDef(log: Logger)(pluginDef: BuildStructure, state: State): Seq[Attributed[File]] = + def evalPluginDef(log: Logger)(pluginDef: BuildStructure, state: State): PluginData = { val root = ProjectRef(pluginDef.root, Load.getRootProject(pluginDef.units)(pluginDef.root)) - val pluginKey = Keys.fullClasspath in Configurations.Runtime + val pluginKey = pluginData val config = defaultConfig(Project.extract(state), pluginDef) val evaluated = apply(pluginDef, ScopedKey(pluginKey.scope, pluginKey.key), state, root, config) - val (newS, result) = evaluated getOrElse error("Plugin classpath does not exist for plugin definition at " + pluginDef.root) + val (newS, result) = evaluated getOrElse error("Plugin data does not exist for plugin definition at " + pluginDef.root) Project.runUnloadHooks(newS) // discard states processResult(result, log) } diff --git a/main/Keys.scala b/main/Keys.scala index 3fe7c5764..52a79757c 100644 --- a/main/Keys.scala +++ b/main/Keys.scala @@ -325,6 +325,7 @@ object Keys val (state, dummyState) = dummy[State]("state", "Current build state.") val (streamsManager, dummyStreamsManager) = dummy[Streams]("streams-manager", "Streams manager, which provides streams for different contexts.") val resolvedScoped = SettingKey[ScopedKey[_]]("resolved-scoped", "The ScopedKey for the referencing setting or task.", DSetting) + val pluginData = TaskKey[PluginData]("plugin-data", "Information from the plugin build needed in the main build definition.", DTask) private[sbt] val parseResult: TaskKey[Any] = TaskKey("$parse-result", "Internal: used to implement input tasks.", Invisible) val triggeredBy = AttributeKey[Seq[Task[_]]]("triggered-by") diff --git a/main/Load.scala b/main/Load.scala index 73dc0bb38..58b8f377b 100755 --- a/main/Load.scala +++ b/main/Load.scala @@ -13,7 +13,7 @@ package sbt import Compiler.{Compilers,Inputs} import inc.{FileValueCache, Locate} import Project.{inScope, ScopedKey, ScopeLocal, Setting} - import Keys.{appConfiguration, baseDirectory, configuration, streams, Streams, thisProject, thisProjectRef} + import Keys.{appConfiguration, baseDirectory, configuration, fullResolvers, fullClasspath, pluginData, streams, Streams, thisProject, thisProjectRef} import Keys.{isDummy, loadedBuild, parseResult, resolvedScoped, taskDefinitionKey} import tools.nsc.reporters.ConsoleReporter import Build.{analyzed, data} @@ -437,6 +437,7 @@ object Load } val autoPluginSettings: Seq[Setting[_]] = inScope(GlobalScope in LocalRootProject)(Seq( Keys.sbtPlugin :== true, + pluginData <<= (fullClasspath in Configurations.Runtime, fullResolvers) map ( (cp, rs) => PluginData(cp, Some(rs)) ), Keys.onLoadMessage <<= Keys.baseDirectory("Loading project definition from " + _) )) def enableSbtPlugin(config: LoadBuildConfiguration): LoadBuildConfiguration = @@ -461,14 +462,15 @@ object Load import Path._ !(dir * -GlobFilter(DefaultTargetName)).get.isEmpty } - def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins = loadPluginDefinition(dir, config, config.globalPluginClasspath) + def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins = + loadPluginDefinition(dir, config, PluginData(config.globalPluginClasspath, None)) def buildPlugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins = loadPluginDefinition(dir, config, buildPluginDefinition(dir, s, config)) - def loadPluginDefinition(dir: File, config: LoadBuildConfiguration, pluginClasspath: Seq[Attributed[File]]): LoadedPlugins = + def loadPluginDefinition(dir: File, config: LoadBuildConfiguration, pluginData: PluginData): LoadedPlugins = { - val (definitionClasspath, pluginLoader) = pluginDefinitionLoader(config, pluginClasspath) - loadPlugins(dir, definitionClasspath, pluginLoader) + val (definitionClasspath, pluginLoader) = pluginDefinitionLoader(config, pluginData.classpath) + loadPlugins(dir, pluginData.copy(classpath = definitionClasspath), pluginLoader) } def pluginDefinitionLoader(config: LoadBuildConfiguration, pluginClasspath: Seq[Attributed[File]]): (Seq[Attributed[File]], ClassLoader) = { @@ -478,7 +480,7 @@ object Load val pluginLoader = if(pluginClasspath.isEmpty) pm.initialLoader else { addToLoader(); pm.loader } (definitionClasspath, pluginLoader) } - def buildPluginDefinition(dir: File, s: State, config: LoadBuildConfiguration): Seq[Attributed[File]] = + def buildPluginDefinition(dir: File, s: State, config: LoadBuildConfiguration): PluginData = { val (eval,pluginDef) = apply(dir, s, config) val pluginState = Project.setProject(Load.initialSession(pluginDef, eval), pluginDef, s) @@ -510,13 +512,13 @@ object Load (inputs, analysis) } - def loadPlugins(dir: File, classpath: Seq[Attributed[File]], loader: ClassLoader): LoadedPlugins = + def loadPlugins(dir: File, data: PluginData, loader: ClassLoader): LoadedPlugins = { - val (pluginNames, plugins) = if(classpath.isEmpty) (Nil, Nil) else { - val names = getPluginNames(classpath, loader) + val (pluginNames, plugins) = if(data.classpath.isEmpty) (Nil, Nil) else { + val names = getPluginNames(data.classpath, loader) (names, loadPlugins(loader, names) ) } - new LoadedPlugins(dir, classpath, loader, plugins, pluginNames) + new LoadedPlugins(dir, data, loader, plugins, pluginNames) } def getPluginNames(classpath: Seq[Attributed[File]], loader: ClassLoader): Seq[String] = ( binaryPlugins(Build.data(classpath), loader) ++ (analyzed(classpath) flatMap findPlugins) ).distinct @@ -581,8 +583,9 @@ object Load final class EvaluatedConfigurations(val eval: Eval, val settings: Seq[Setting[_]]) final class LoadedDefinitions(val base: File, val target: Seq[File], val loader: ClassLoader, val builds: Seq[Build], val buildNames: Seq[String]) - final class LoadedPlugins(val base: File, val fullClasspath: Seq[Attributed[File]], val loader: ClassLoader, val plugins: Seq[Plugin], val pluginNames: Seq[String]) + final class LoadedPlugins(val base: File, val pluginData: PluginData, val loader: ClassLoader, val plugins: Seq[Plugin], val pluginNames: Seq[String]) { + def fullClasspath: Seq[Attributed[File]] = pluginData.classpath def classpath = data(fullClasspath) } final class BuildUnit(val uri: URI, val localBase: File, val definitions: LoadedDefinitions, val plugins: LoadedPlugins) @@ -646,7 +649,7 @@ object Load 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, + compilers: Compilers, evalPluginDef: (BuildStructure, State) => PluginData, definesClass: DefinesClass, delegates: LoadedBuild => Scope => Seq[Scope], scopeLocal: ScopeLocal, pluginManagement: PluginManagement, injectSettings: InjectSettings, globalPlugin: Option[GlobalPlugin], log: Logger) { diff --git a/sbt/src/sbt-test/dependency-management/update-sbt-classifiers/project/plugins.sbt b/sbt/src/sbt-test/dependency-management/update-sbt-classifiers/project/plugins.sbt new file mode 100644 index 000000000..4a1f440c2 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/update-sbt-classifiers/project/plugins.sbt @@ -0,0 +1,3 @@ +resolvers += Resolver.url("sbt-plugin-snapshots", url("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-snapshots/"))(Resolver.ivyStylePatterns) + +addSbtPlugin("com.eed3si9n" % "sbt-twt" % "0.2.1-SNAPSHOT", sbtVersion="0.12.0-M2") diff --git a/sbt/src/sbt-test/dependency-management/update-sbt-classifiers/test b/sbt/src/sbt-test/dependency-management/update-sbt-classifiers/test new file mode 100644 index 000000000..f7bc09621 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/update-sbt-classifiers/test @@ -0,0 +1 @@ +> update-sbt-classifiers