use resolvers configured in plugin definition for update-sbt-classifiers. fixes #304.

This commit is contained in:
Mark Harrah 2012-04-01 23:19:08 -04:00
parent 6fb1934efa
commit 6015d082aa
6 changed files with 30 additions and 19 deletions

View File

@ -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)
))

View File

@ -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)
}

View File

@ -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")

View File

@ -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)
{

View File

@ -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")

View File

@ -0,0 +1 @@
> update-sbt-classifiers