mirror of https://github.com/sbt/sbt.git
reimplement lighter support for controlling aggregation
This commit is contained in:
parent
82326cc899
commit
795b924f46
|
|
@ -26,7 +26,7 @@ object Act
|
|||
// the index should be an aggregated index for proper tab completion
|
||||
def scopedKeyAggregated(current: ProjectRef, defaultConfigs: Option[ResolvedReference] => Seq[String], structure: BuildStructure): KeysParser =
|
||||
for(selected <- scopedKeySelected(structure.index.aggregateKeyIndex, current, defaultConfigs, structure.index.keyMap, structure.data) ) yield
|
||||
Resolve.aggregateDeps(selected.key, selected.mask, structure.extra)
|
||||
Aggregation.aggregate(selected.key, selected.mask, structure.extra)
|
||||
|
||||
def scopedKeySelected(index: KeyIndex, current: ProjectRef, defaultConfigs: Option[ResolvedReference] => Seq[String],
|
||||
keyMap: Map[String, AttributeKey[_]], data: Settings[Scope]): Parser[ParsedKey] =
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
package sbt
|
||||
|
||||
import Project.ScopedKey
|
||||
import Load.BuildStructure
|
||||
import Load.{BuildStructure,LoadedBuildUnit}
|
||||
import Keys.{aggregate, showSuccess, showTiming, timingFormat}
|
||||
import sbt.complete.Parser
|
||||
import java.net.URI
|
||||
|
|
@ -14,13 +14,6 @@ package sbt
|
|||
sealed trait Aggregation
|
||||
final object Aggregation
|
||||
{
|
||||
def apply(dependencies: Seq[ProjectReference], transitive: Boolean = true): Aggregation = new Explicit(dependencies, transitive)
|
||||
implicit def fromBoolean(b: Boolean): Aggregation = if(b) Enabled else Disabled
|
||||
val Enabled = new Implicit(true)
|
||||
val Disabled = new Implicit(false)
|
||||
final case class Implicit(enabled: Boolean) extends Aggregation
|
||||
final class Explicit(val dependencies: Seq[ProjectReference], val transitive: Boolean) extends Aggregation
|
||||
|
||||
final case class KeyValue[+T](key: ScopedKey[_], value: T)
|
||||
|
||||
def printSettings[T](xs: Seq[KeyValue[T]], log: Logger)(implicit display: Show[ScopedKey[_]]) =
|
||||
|
|
@ -118,4 +111,56 @@ final object Aggregation
|
|||
}
|
||||
private[this] def maps[T, S](vs: Values[T])(f: T => S): Values[S] =
|
||||
vs map { case KeyValue(k,v) => KeyValue(k, f(v)) }
|
||||
|
||||
|
||||
def projectAggregates[Proj](proj: Option[Reference], extra: BuildUtil[Proj], reverse: Boolean): Seq[ProjectRef] =
|
||||
{
|
||||
val resRef = proj.map(p => extra.projectRefFor(extra.resolveRef(p)))
|
||||
resRef.toList.flatMap(ref =>
|
||||
if(reverse) extra.aggregates.reverse(ref) else extra.aggregates.forward(ref)
|
||||
)
|
||||
}
|
||||
|
||||
def aggregate[T, Proj](key: ScopedKey[T], rawMask: ScopeMask, extra: BuildUtil[Proj], reverse: Boolean = false): Seq[ScopedKey[T]] =
|
||||
{
|
||||
val mask = rawMask.copy(project = true)
|
||||
Dag.topologicalSort(key) { k =>
|
||||
if(reverse)
|
||||
reverseAggregatedKeys(k, extra, mask)
|
||||
else if(aggregationEnabled(key, extra.data))
|
||||
aggregatedKeys(k, extra, mask)
|
||||
else
|
||||
Nil
|
||||
}
|
||||
}
|
||||
def reverseAggregatedKeys[T](key: ScopedKey[T], extra: BuildUtil[_], mask: ScopeMask): Seq[ScopedKey[T]] =
|
||||
projectAggregates(key.scope.project.toOption, extra, reverse = true) flatMap { ref =>
|
||||
val toResolve = key.scope.copy(project = Select(ref))
|
||||
val resolved = Resolve(extra, Global, key.key, mask)(toResolve)
|
||||
val skey = ScopedKey(resolved, key.key)
|
||||
if( aggregationEnabled(skey, extra.data) ) skey :: Nil else Nil
|
||||
}
|
||||
|
||||
def aggregatedKeys[T](key: ScopedKey[T], extra: BuildUtil[_], mask: ScopeMask): Seq[ScopedKey[T]] =
|
||||
projectAggregates(key.scope.project.toOption, extra, reverse = false) map { ref =>
|
||||
val toResolve = key.scope.copy(project = Select(ref))
|
||||
val resolved = Resolve(extra, Global, key.key, mask)(toResolve)
|
||||
ScopedKey(resolved, key.key)
|
||||
}
|
||||
|
||||
def aggregationEnabled(key: ScopedKey[_], data: Settings[Scope]): Boolean =
|
||||
Keys.aggregate in Scope.fillTaskAxis(key.scope, key.key) get data getOrElse true
|
||||
|
||||
def relation(units: Map[URI, LoadedBuildUnit]): Relation[ProjectRef, ProjectRef] =
|
||||
{
|
||||
val depPairs =
|
||||
for {
|
||||
(uri, unit) <- units.toIterable
|
||||
project <- unit.defined.values
|
||||
ref = ProjectRef(uri, project.id)
|
||||
agg <- project.aggregate
|
||||
} yield
|
||||
(ref, agg)
|
||||
Relation.empty ++ depPairs
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import java.net.URI
|
|||
|
||||
final class BuildUtil[Proj](
|
||||
val keyIndex: KeyIndex,
|
||||
val data: Settings[Scope],
|
||||
val root: URI,
|
||||
val rootProjectID: URI => String,
|
||||
val project: (URI, String) => Proj,
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ object Defaults extends BuildCommon
|
|||
sbtPlugin :== false,
|
||||
crossPaths :== true,
|
||||
classpathTypes :== Set("jar", "bundle"),
|
||||
aggregate :== Aggregation.Enabled,
|
||||
aggregate :== true,
|
||||
maxErrors :== 100,
|
||||
showTiming :== true,
|
||||
timingFormat :== Aggregation.defaultFormat,
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ private final class KeyIndex0(val data: BuildIndex) extends ExtendableKeyIndex
|
|||
def addAggregated(scoped: ScopedKey[_], extra: BuildUtil[_]): ExtendableKeyIndex =
|
||||
if(validID(scoped.key.label))
|
||||
{
|
||||
val aggregateProjects = Resolve.aggregateDeps(scoped, ScopeMask(), extra, reverse = true)
|
||||
val aggregateProjects = Aggregation.aggregate(scoped, ScopeMask(), extra, reverse = true)
|
||||
((this: ExtendableKeyIndex) /: aggregateProjects)(_ add _)
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ object Keys
|
|||
val definesClass = TaskKey[DefinesClass]("defines-class", "Internal use: provides a function that determines whether the provided file contains a given class.")
|
||||
val doc = TaskKey[File]("doc", "Generates API documentation.")
|
||||
val copyResources = TaskKey[Seq[(File,File)]]("copy-resources", "Copies resources to the output directory.")
|
||||
val aggregate = SettingKey[Aggregation]("aggregate", "Configures task aggregation.")
|
||||
val aggregate = SettingKey[Boolean]("aggregate", "Configures task aggregation.")
|
||||
|
||||
// package keys
|
||||
val packageBin = TaskKey[File]("package-bin", "Produces a main artifact, such as a binary jar.")
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ object Load
|
|||
val settings = finalTransforms(buildConfigurations(loaded, getRootProject(projects), rootEval, config.injectSettings))
|
||||
val delegates = config.delegates(loaded)
|
||||
val data = Project.makeSettings(settings, delegates, config.scopeLocal)( Project.showLoadingKey( loaded ) )
|
||||
val index = structureIndex(data, settings, loaded.extra)
|
||||
val index = structureIndex(data, settings, loaded.extra(data))
|
||||
val streams = mkStreams(projects, loaded.root, data)
|
||||
(rootEval, new BuildStructure(projects, loaded.root, settings, data, index, streams, delegates, config.scopeLocal))
|
||||
}
|
||||
|
|
@ -175,7 +175,7 @@ object Load
|
|||
{
|
||||
val transformed = finalTransforms(newSettings)
|
||||
val newData = Project.makeSettings(transformed, structure.delegates, structure.scopeLocal)
|
||||
val newIndex = structureIndex(newData, transformed, index => buildUtil(structure.root, structure.units, index))
|
||||
val newIndex = structureIndex(newData, transformed, index => buildUtil(structure.root, structure.units, index, newData))
|
||||
val newStreams = mkStreams(structure.units, structure.root, newData)
|
||||
new BuildStructure(units = structure.units, root = structure.root, settings = transformed, data = newData, index = newIndex, streams = newStreams, delegates = structure.delegates, scopeLocal = structure.scopeLocal)
|
||||
}
|
||||
|
|
@ -547,7 +547,7 @@ object Load
|
|||
{
|
||||
checkCycles(units)
|
||||
def allProjectRefs: Seq[(ProjectRef, ResolvedProject)] = for( (uri, unit) <- units.toSeq; (id, proj) <- unit.defined ) yield ProjectRef(uri, id) -> proj
|
||||
def extra(keyIndex: KeyIndex): BuildUtil[ResolvedProject] = buildUtil(root, units, keyIndex)
|
||||
def extra(data: Settings[Scope])(keyIndex: KeyIndex): BuildUtil[ResolvedProject] = buildUtil(root, units, keyIndex, data)
|
||||
}
|
||||
def checkCycles(units: Map[URI, LoadedBuildUnit])
|
||||
{
|
||||
|
|
@ -588,15 +588,15 @@ object Load
|
|||
def allProjects(build: URI): Seq[ResolvedProject] = units(build).defined.values.toSeq
|
||||
def allProjectRefs: Seq[ProjectRef] = units.toSeq flatMap { case (build, unit) => refs(build, unit.defined.values.toSeq) }
|
||||
def allProjectRefs(build: URI): Seq[ProjectRef] = refs(build, allProjects(build))
|
||||
val extra: BuildUtil[ResolvedProject] = buildUtil(root, units, index.keyIndex)
|
||||
val extra: BuildUtil[ResolvedProject] = buildUtil(root, units, index.keyIndex, data)
|
||||
private[this] def refs(build: URI, projects: Seq[ResolvedProject]): Seq[ProjectRef] = projects.map { p => ProjectRef(build, p.id) }
|
||||
}
|
||||
def buildUtil(root: URI, units: Map[URI, LoadedBuildUnit], keyIndex: KeyIndex): BuildUtil[ResolvedProject] =
|
||||
def buildUtil(root: URI, units: Map[URI, LoadedBuildUnit], keyIndex: KeyIndex, data: Settings[Scope]): BuildUtil[ResolvedProject] =
|
||||
{
|
||||
val getp = (build: URI, project: String) => Load.getProject(units, build, project)
|
||||
val configs = (_: ResolvedProject).configurations.map(c => ConfigKey(c.name))
|
||||
val aggregates = Resolve.aggregates(units)
|
||||
new BuildUtil(keyIndex, root, Load getRootProject units, getp, configs, aggregates)
|
||||
val aggregates = Aggregation.relation(units)
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ final case class Extracted(structure: BuildStructure, session: SessionSettings,
|
|||
def runAggregated[T](key: TaskKey[T], state: State): State =
|
||||
{
|
||||
val rkey = resolve(key.scopedKey)
|
||||
val keys = Resolve.aggregateDeps(rkey, ScopeMask(), structure.extra)
|
||||
val keys = Aggregation.aggregate(rkey, ScopeMask(), structure.extra)
|
||||
val tasks = Act.keyValues(structure)(keys)
|
||||
Aggregation.runTasks(state, structure, tasks, Aggregation.Dummies(KNil, HNil), show = false )(showKey)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package sbt
|
||||
|
||||
import java.net.URI
|
||||
import Load.LoadedBuildUnit
|
||||
|
||||
object Resolve
|
||||
{
|
||||
|
|
@ -43,42 +42,4 @@ object Resolve
|
|||
val config: ScopeAxis[ConfigKey] = (Global +: projectConfigs) find definesKey getOrElse Global
|
||||
scope.copy(config = config)
|
||||
}
|
||||
|
||||
import Load.BuildStructure
|
||||
import Project.ScopedKey
|
||||
|
||||
def projectAggregate[Proj](proj: Option[Reference], extra: BuildUtil[Proj], reverse: Boolean): Seq[ProjectRef] =
|
||||
{
|
||||
val resRef = proj.map(p => extra.projectRefFor(extra.resolveRef(p)))
|
||||
resRef.toList.flatMap(ref =>
|
||||
if(reverse) extra.aggregates.reverse(ref) else extra.aggregates.forward(ref)
|
||||
)
|
||||
}
|
||||
|
||||
def aggregateDeps[T, Proj](key: ScopedKey[T], rawMask: ScopeMask, extra: BuildUtil[Proj], reverse: Boolean = false): Seq[ScopedKey[T]] =
|
||||
{
|
||||
val mask = rawMask.copy(project = true)
|
||||
Dag.topologicalSort(key) { k =>
|
||||
val kref = k.scope.project
|
||||
for( ref <- projectAggregate(kref.toOption, extra, reverse)) yield
|
||||
{
|
||||
val toResolve = k.scope.copy(project = Select(ref))
|
||||
val resolved = apply(extra, Global, k.key, mask)(toResolve)
|
||||
ScopedKey(resolved, k.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def aggregates(units: Map[URI, LoadedBuildUnit]): Relation[ProjectRef, ProjectRef] =
|
||||
{
|
||||
val depPairs =
|
||||
for {
|
||||
(uri, unit) <- units.toIterable
|
||||
project <- unit.defined.values
|
||||
ref = ProjectRef(uri, project.id)
|
||||
agg <- project.aggregate
|
||||
} yield
|
||||
(ref, agg)
|
||||
Relation.empty ++ depPairs
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ object TestBuild
|
|||
val extra: BuildUtil[Proj] =
|
||||
{
|
||||
val getp = (build: URI, project: String) => env.buildMap(build).projectMap(project)
|
||||
new BuildUtil(keyIndex, env.root.uri, env.rootProject, getp, _.configurations.map(c => ConfigKey(c.name)), const(Nil))
|
||||
new BuildUtil(keyIndex, data, env.root.uri, env.rootProject, getp, _.configurations.map(c => ConfigKey(c.name)), Relation.empty)
|
||||
}
|
||||
|
||||
lazy val allAttributeKeys: Set[AttributeKey[_]] = data.data.values.flatMap(_.keys).toSet
|
||||
|
|
|
|||
Loading…
Reference in New Issue