mirror of https://github.com/sbt/sbt.git
redid global plugins for proper classpath handling and preparation for global settings (pending)
This commit is contained in:
parent
60dcd4404f
commit
353be43978
|
|
@ -0,0 +1,49 @@
|
|||
package sbt
|
||||
|
||||
import Load._
|
||||
import Project._
|
||||
import Scoped._
|
||||
import Keys._
|
||||
import Configurations.Compile
|
||||
import java.io.File
|
||||
import org.apache.ivy.core.module.{descriptor, id}
|
||||
import descriptor.ModuleDescriptor, id.ModuleRevisionId
|
||||
|
||||
object GlobalPlugin
|
||||
{
|
||||
// constructs a sequence of settings that may be appended to a project's settings to
|
||||
// statically add the global plugin as a classpath dependency.
|
||||
// static here meaning that the relevant tasks for the global plugin have already been evaluated
|
||||
def inject(gp: GlobalPluginData): Seq[Setting[_]] =
|
||||
Seq[Setting[_]](
|
||||
projectDescriptors ~= { _ ++ gp.descriptors },
|
||||
projectDependencies ++= gp.projectID +: gp.dependencies,
|
||||
internalDependencyClasspath in Compile ~= { prev => (prev ++ gp.internalClasspath).distinct }
|
||||
)
|
||||
|
||||
def build(base: File, s: State, config: LoadBuildConfiguration): BuildStructure = Load(base, s, config)._2
|
||||
def load(base: File, s: State, config: LoadBuildConfiguration): GlobalPlugin =
|
||||
{
|
||||
val structure = build(base, s, config)
|
||||
val data = extract(s, structure)
|
||||
GlobalPlugin(data, structure, inject(data))
|
||||
}
|
||||
def extract(state: State, structure: BuildStructure): GlobalPluginData =
|
||||
{
|
||||
import structure.{data, root}
|
||||
val p = RootProject(root)
|
||||
val task = (projectID in p, projectDependencies in p, projectDescriptors in p, fullClasspath in (p, Compile), internalDependencyClasspath in (p, Compile) ) map GlobalPluginData.apply get data
|
||||
evaluate(state, structure, task)
|
||||
}
|
||||
def evaluate[T](state: State, structure: BuildStructure, t: Task[T]): T =
|
||||
{
|
||||
import EvaluateTask._
|
||||
val log = CommandSupport.logger(state)
|
||||
withStreams(structure) { str =>
|
||||
val nv = nodeView(state, str)
|
||||
processResult(runTask(t, str, structure.index.triggers)(nv), log)
|
||||
}
|
||||
}
|
||||
}
|
||||
final case class GlobalPluginData(projectID: ModuleID, dependencies: Seq[ModuleID], descriptors: Map[ModuleRevisionId, ModuleDescriptor], fullClasspath: Seq[Attributed[File]], internalClasspath: Seq[Attributed[File]])
|
||||
final case class GlobalPlugin(data: GlobalPluginData, structure: BuildStructure, inject: Seq[Setting[_]])
|
||||
|
|
@ -36,16 +36,20 @@ object Load
|
|||
val compilers = Compiler.compilers(ClasspathOptions.boot)(state.configuration, log)
|
||||
val evalPluginDef = EvaluateTask.evalPluginDef(log) _
|
||||
val delegates = defaultDelegates
|
||||
val inject: Seq[Project.Setting[_]] = ((appConfiguration in GlobalScope) :== state.configuration) +: EvaluateTask.injectSettings
|
||||
val injectGlobal: Seq[Project.Setting[_]] = ((appConfiguration in GlobalScope) :== state.configuration) +: EvaluateTask.injectSettings
|
||||
val inject = InjectSettings(injectGlobal, Nil)
|
||||
val definesClass = FileValueCache(Locate.definesClass _)
|
||||
val rawConfig = new LoadBuildConfiguration(stagingDirectory, classpath, loader, compilers, evalPluginDef, definesClass.get, delegates, EvaluateTask.injectStreams, inject, Nil, log)
|
||||
val rawConfig = new LoadBuildConfiguration(stagingDirectory, classpath, loader, compilers, evalPluginDef, definesClass.get, delegates, EvaluateTask.injectStreams, inject, None, log)
|
||||
val config = loadGlobal(state, baseDirectory, defaultGlobalPlugins, rawConfig)
|
||||
val result = apply(base, state, config)
|
||||
definesClass.clear()
|
||||
result
|
||||
}
|
||||
def loadGlobal(state: State, base: File, global: File, config: LoadBuildConfiguration): LoadBuildConfiguration = config
|
||||
|
||||
def loadGlobal(state: State, base: File, global: File, config: LoadBuildConfiguration): LoadBuildConfiguration =
|
||||
if(base != global && global.exists)
|
||||
config.copy(globalPlugin = Some(GlobalPlugin.load(global, state, config)))
|
||||
else
|
||||
config
|
||||
def defaultDelegates: LoadedBuild => Scope => Seq[Scope] = (lb: LoadedBuild) => {
|
||||
val rootProject = getRootProject(lb.units)
|
||||
def resolveRef(project: Reference): ResolvedReference = Scope.resolveReference(lb.root, rootProject, project)
|
||||
|
|
@ -87,7 +91,7 @@ object Load
|
|||
val loaded = resolveProjects(load(rootBase, s, config))
|
||||
val projects = loaded.units
|
||||
lazy val rootEval = lazyEval(loaded.units(loaded.root).unit)
|
||||
val settings = finalTransforms(config.injectSettings ++ buildConfigurations(loaded, getRootProject(projects), rootEval))
|
||||
val settings = finalTransforms(config.injectSettings.global ++ buildConfigurations(loaded, getRootProject(projects), rootEval, config.injectSettings.project))
|
||||
val delegates = config.delegates(loaded)
|
||||
val data = Project.makeSettings(settings, delegates, config.scopeLocal)
|
||||
val index = structureIndex(data)
|
||||
|
|
@ -133,7 +137,7 @@ object Load
|
|||
}
|
||||
|
||||
def isProjectThis(s: Setting[_]) = s.key.scope.project match { case This | Select(ThisProject) => true; case _ => false }
|
||||
def buildConfigurations(loaded: LoadedBuild, rootProject: URI => String, rootEval: () => Eval): Seq[Setting[_]] =
|
||||
def buildConfigurations(loaded: LoadedBuild, rootProject: URI => String, rootEval: () => Eval, injectProjectSettings: Seq[Setting[_]]): Seq[Setting[_]] =
|
||||
loaded.units.toSeq flatMap { case (uri, build) =>
|
||||
val eval = if(uri == loaded.root) rootEval else lazyEval(build.unit)
|
||||
val pluginSettings = build.unit.plugins.plugins
|
||||
|
|
@ -145,7 +149,7 @@ object Load
|
|||
val settings =
|
||||
(thisProject :== project) +:
|
||||
(thisProjectRef :== ref) +:
|
||||
(defineConfig ++ project.settings ++ pluginThisProject ++ configurations(srcs, eval, build.imports))
|
||||
(defineConfig ++ project.settings ++ pluginThisProject ++ configurations(srcs, eval, build.imports) ++ injectProjectSettings )
|
||||
|
||||
// map This to thisScope, Select(p) to mapRef(uri, rootProject, p)
|
||||
transformSettings(projectScope(ref), uri, rootProject, settings)
|
||||
|
|
@ -333,13 +337,25 @@ object Load
|
|||
new BuildUnit(uri, normBase, loadedDefs, plugs)
|
||||
}
|
||||
|
||||
def globalPluginClasspath(config: LoadBuildConfiguration): Seq[Attributed[File]] =
|
||||
config.globalPlugin match
|
||||
{
|
||||
case Some(cp) => cp.data.fullClasspath
|
||||
case None => Nil
|
||||
}
|
||||
def activateGlobalPlugin(config: LoadBuildConfiguration): LoadBuildConfiguration =
|
||||
config.globalPlugin match
|
||||
{
|
||||
case Some(gp) => config.copy(injectSettings = config.injectSettings.copy(project = gp.inject) )
|
||||
case None => config
|
||||
}
|
||||
def plugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins =
|
||||
if(dir.exists)
|
||||
buildPlugins(dir, s, config)
|
||||
buildPlugins(dir, s, activateGlobalPlugin(config))
|
||||
else
|
||||
noPlugins(dir, config)
|
||||
|
||||
def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins = loadPluginDefinition(dir, config, Nil)
|
||||
def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins = loadPluginDefinition(dir, config, globalPluginClasspath(config))
|
||||
def buildPlugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins =
|
||||
loadPluginDefinition(dir, config, buildPluginDefinition(dir, s, config))
|
||||
|
||||
|
|
@ -482,7 +498,8 @@ object Load
|
|||
def allProjectRefs(build: URI): Seq[ProjectRef] = refs(build, allProjects(build))
|
||||
private[this] def refs(build: URI, projects: Seq[ResolvedProject]): Seq[ProjectRef] = projects.map { p => ProjectRef(build, p.id) }
|
||||
}
|
||||
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: Seq[Setting[_]], injectDependencies: Seq[ClasspathDependency], 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, injectSettings: InjectSettings, globalPlugin: Option[GlobalPlugin], log: Logger)
|
||||
final case class InjectSettings(global: Seq[Setting[_]], project: Seq[Setting[_]])
|
||||
|
||||
// information that is not original, but can be reconstructed from the rest of BuildStructure
|
||||
final class StructureIndex(val keyMap: Map[String, AttributeKey[_]], val taskToKey: Map[Task[_], ScopedKey[Task[_]]], val triggers: Triggers[Task], val keyIndex: KeyIndex)
|
||||
|
|
|
|||
Loading…
Reference in New Issue