make "globals" per-build definition

This commit is contained in:
Mark Harrah 2011-02-27 16:28:00 -05:00
parent 0729798cce
commit 98bd962952
4 changed files with 44 additions and 30 deletions

View File

@ -10,16 +10,18 @@ package sbt
import scala.annotation.tailrec
import collection.mutable
import Compile.{Compilers,Inputs}
import Project.{ScopedKey, ScopeLocal, Setting}
import Project.{inScope, ScopedKey, ScopeLocal, Setting}
import Keys.{AppConfig, Config, ThisProject, ThisProjectRef}
import TypeFunctions.{Endo,Id}
import tools.nsc.reporters.ConsoleReporter
import Build.{analyzed, data}
import Scope.{GlobalScope, ThisScope}
// name is more like BuildDefinition, but that is too long
trait Build
{
def projects: Seq[Project]
def settings: Seq[Setting[_]] = Default.buildCore
}
trait Plugin
{
@ -114,8 +116,8 @@ object EvaluateTask
private[sbt] val parseResult: TaskKey[_] = TaskKey("$parse-result")
def injectSettings: Seq[Project.Setting[_]] = Seq(
(state in Scope.GlobalScope) ::= dummyState,
(streamsManager in Scope.GlobalScope) ::= dummyStreamsManager
(state in GlobalScope) ::= dummyState,
(streamsManager in GlobalScope) ::= dummyStreamsManager
)
def dummy[T](name: String): (TaskKey[T], Task[T]) = (TaskKey[T](name), dummyTask(name))
@ -221,7 +223,7 @@ object Load
val compilers = Compile.compilers(state.configuration, log)
val evalPluginDef = EvaluateTask.evalPluginDef(log) _
val delegates = memo(defaultDelegates)
val inject: Seq[Project.Setting[_]] = ((AppConfig in Scope.GlobalScope) :== state.configuration) +: EvaluateTask.injectSettings
val inject: Seq[Project.Setting[_]] = ((AppConfig in GlobalScope) :== state.configuration) +: EvaluateTask.injectSettings
val config = new LoadBuildConfiguration(stagingDirectory, classpath, loader, compilers, evalPluginDef, delegates, EvaluateTask.injectStreams, inject, log)
apply(base, state, config)
}
@ -312,7 +314,8 @@ object Load
// map This to thisScope, Select(p) to mapRef(uri, rootProject, p)
transformSettings(projectScope(uri, id), uri, rootProject, settings)
}
pluginGlobal ++ projectSettings
val buildScope = ThisScope.copy(project = Select(ProjectRef(Some(uri), None)))
pluginGlobal ++ inScope(buildScope)(build.buildSettings) ++ projectSettings
}
def transformSettings(thisScope: Scope, uri: URI, rootProject: URI => String, settings: Seq[Setting[_]]): Seq[Setting[_]] =
Project.transform(Scope.resolveScope(thisScope, uri, rootProject), settings)
@ -354,8 +357,10 @@ object Load
val externals = referenced(defined).toList
val projectsInRoot = defined.filter(isRoot).map(_.id)
val rootProjects = if(projectsInRoot.isEmpty) defined.head.id :: Nil else projectsInRoot
(new LoadedBuildUnit(unit, defined.map(d => (d.id, d)).toMap, rootProjects), externals)
(new LoadedBuildUnit(unit, defined.map(d => (d.id, d)).toMap, rootProjects, buildSettings(unit)), externals)
}
def buildSettings(unit: BuildUnit): Seq[Setting[_]] =
unit.definitions.builds.flatMap(_.settings)
@tailrec def loadAll(bases: List[URI], references: Map[URI, List[ProjectRef]], externalLoader: URI => BuildUnit, builds: Map[URI, LoadedBuildUnit]): (Map[URI, List[ProjectRef]], Map[URI, LoadedBuildUnit]) =
bases match
@ -419,7 +424,7 @@ object Load
{
IO.assertAbsolute(uri)
val resolve = resolveProject(ref => Scope.mapRef(uri, rootProject, ref))
new LoadedBuildUnit(unit.unit, unit.defined mapValues resolve, unit.rootProjects)
new LoadedBuildUnit(unit.unit, unit.defined mapValues resolve, unit.rootProjects, unit.buildSettings)
}
def resolveProject(resolveRef: ProjectRef => ProjectRef): Project => Project =
{
@ -557,7 +562,7 @@ object Load
}
final class LoadedBuild(val root: URI, val units: Map[URI, LoadedBuildUnit])
final class LoadedBuildUnit(val unit: BuildUnit, val defined: Map[String, Project], val rootProjects: Seq[String])
final class LoadedBuildUnit(val unit: BuildUnit, val defined: Map[String, Project], val rootProjects: Seq[String], val buildSettings: Seq[Setting[_]])
{
assert(!rootProjects.isEmpty, "No root projects defined for build unit " + unit)
def localBase = unit.localBase

View File

@ -5,8 +5,8 @@ package sbt
import java.io.File
import Build.data
import Scope.{GlobalScope,ThisScope}
import Project.{Initialize, ScopedKey, Setting}
import Scope.{GlobalScope, ThisScope}
import Project.{inConfig, Initialize, inScope, inTask, ScopedKey, Setting}
import Configurations.{Compile => CompileConf, Test => TestConf}
import EvaluateTask.{resolvedScoped, streams}
import complete._
@ -53,19 +53,21 @@ object Default
def analysisMap[T](cp: Seq[Attributed[T]]): Map[T, inc.Analysis] =
(cp map extractAnalysis).toMap
def core: Seq[Setting[_]] = Seq(
JavaHome in GlobalScope :== None,
OutputStrategy in GlobalScope :== None,
Fork in GlobalScope :== false,
JavaOptions in GlobalScope :== Nil,
def buildCore: Seq[Setting[_]] = inScope(GlobalScope)(Seq(
JavaHome :== None,
OutputStrategy :== None,
Fork :== false,
JavaOptions :== Nil,
CrossPaths :== true,
ShellPrompt in GlobalScope :== (_ => "> "),
Aggregate in GlobalScope :== Aggregation.Enabled,
Name <<= ThisProject(_.id),
Version :== "0.1",
MaxErrors in GlobalScope :== 100,
ShellPrompt :== (_ => "> "),
Aggregate :== Aggregation.Enabled,
MaxErrors :== 100,
Commands :== Nil,
Data <<= EvaluateTask.state map { state => Project.structure(state).data }
))
def projectCore: Seq[Setting[_]] = Seq(
Name <<= ThisProject(_.id),
Version :== "0.1"
)
def paths = Seq(
Base <<= ThisProject(_.base),
@ -303,13 +305,6 @@ object Default
val CompletionsID = "completions"
def inConfig(conf: Configuration)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
inScope(ThisScope.copy(config = Select(conf)) )( (Config :== conf) +: ss)
def inTask(t: Scoped)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
inScope(ThisScope.copy(task = Select(t.key)) )( ss )
def inScope(scope: Scope)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
Project.transform(Scope.replaceThis(scope), ss)
lazy val defaultWebPaths = inConfig(CompileConf)(webPaths)
def noAggregation = Seq(RunTask, ConsoleTask, ConsoleQuick)
@ -330,7 +325,7 @@ object Default
lazy val itSettings = inConfig(Configurations.IntegrationTest)(testSettings)
lazy val defaultConfigs = inConfig(CompileConf)(compileSettings) ++ inConfig(TestConf)(testSettings)
lazy val defaultSettings: Seq[Setting[_]] = core ++ paths ++ baseClasspaths ++ baseTasks ++ compileBase ++ defaultConfigs ++ disableAggregation
lazy val defaultSettings: Seq[Setting[_]] = projectCore ++ paths ++ baseClasspaths ++ baseTasks ++ compileBase ++ defaultConfigs ++ disableAggregation
lazy val defaultWebSettings = defaultSettings ++ defaultWebPaths ++ defaultWebTasks
}
object Classpaths

View File

@ -8,6 +8,7 @@ package sbt
import Project._
import Types.Endo
import Keys.{AppConfig, Commands, Config, HistoryPath, ProjectCommand, SessionKey, ShellPrompt, StructureKey, ThisProject, ThisProjectRef, Watch}
import Scope.ThisScope
import CommandSupport.logger
import compile.Eval
@ -153,6 +154,13 @@ object Project extends Init[Scope]
}
def reverseDependencies(cMap: CompiledMap, scoped: ScopedKey[_]): Iterable[ScopedKey[_]] =
for( (key,compiled) <- cMap; dep <- compiled.dependencies if dep == scoped) yield key
def inConfig(conf: Configuration)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
inScope(ThisScope.copy(config = Select(conf)) )( (Config :== conf) +: ss)
def inTask(t: Scoped)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
inScope(ThisScope.copy(task = Select(t.key)) )( ss )
def inScope(scope: Scope)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
Project.transform(Scope.replaceThis(scope), ss)
}
import SessionSettings._

View File

@ -98,10 +98,16 @@ object Scope
} yield
Scope(Select(proj),c,t,e)
val projI =
linearize(scope.project)(projectInherit) map { p => scope.copy(project = p) }
withRawBuilds(linearize(scope.project)(projectInherit)) map { p => scope.copy(project = p) }
(prod ++ projI :+ GlobalScope).toList.removeDuplicates
(prod ++ projI :+ GlobalScope).distinct
}
def withRawBuilds(ps: Seq[ScopeAxis[ProjectRef]]): Seq[ScopeAxis[ProjectRef]] =
ps ++ ps.flatMap(rawBuilds).distinct.map(Select.apply)
def rawBuilds(ps: ScopeAxis[ProjectRef]): Seq[ProjectRef] = ps match { case Select(ref) => rawBuilds(ref); case _ => Nil }
def rawBuilds(ps: ProjectRef): Seq[ProjectRef] = ps.uri.map(uri => ProjectRef(Some(uri), None)).toList
def linearize[T](axis: ScopeAxis[T])(inherit: T => Seq[T]): Seq[ScopeAxis[T]] =
axis match
{