mirror of https://github.com/sbt/sbt.git
fixes #280. sort aggregate and classpath dependencies separately to keep cycle detection for them separate
This commit is contained in:
parent
2f52884df8
commit
f3f4bea2d5
|
|
@ -576,8 +576,18 @@ object Defaults extends BuildCommon
|
||||||
|
|
||||||
def transitiveDependencies(base: ProjectRef, structure: LoadedBuild, includeRoot: Boolean, classpath: Boolean = true, aggregate: Boolean = false): Seq[ProjectRef] =
|
def transitiveDependencies(base: ProjectRef, structure: LoadedBuild, includeRoot: Boolean, classpath: Boolean = true, aggregate: Boolean = false): Seq[ProjectRef] =
|
||||||
{
|
{
|
||||||
val full = Dag.topologicalSort(base)(getDependencies(structure, classpath, aggregate))
|
def tdeps(enabled: Boolean, f: ProjectRef => Seq[ProjectRef]): Seq[ProjectRef] =
|
||||||
if(includeRoot) full else full.dropRight(1)
|
{
|
||||||
|
val full = if(enabled) Dag.topologicalSort(base)(f) else Nil
|
||||||
|
if(includeRoot) full else full dropRight 1
|
||||||
|
}
|
||||||
|
def fullCp = tdeps(classpath, getDependencies(structure, classpath=true, aggregate=false))
|
||||||
|
def fullAgg = tdeps(aggregate, getDependencies(structure, classpath=false, aggregate=true))
|
||||||
|
(classpath, aggregate) match {
|
||||||
|
case (true, true) => (fullCp ++ fullAgg).distinct
|
||||||
|
case (true, false) => fullCp
|
||||||
|
case _ => fullAgg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
def getDependencies(structure: LoadedBuild, classpath: Boolean = true, aggregate: Boolean = false): ProjectRef => Seq[ProjectRef] =
|
def getDependencies(structure: LoadedBuild, classpath: Boolean = true, aggregate: Boolean = false): ProjectRef => Seq[ProjectRef] =
|
||||||
ref => Project.getProject(ref, structure).toList flatMap { p =>
|
ref => Project.getProject(ref, structure).toList flatMap { p =>
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
def setCond[T](key: AttributeKey[T], vopt: Option[T], attributes: AttributeMap): AttributeMap =
|
def setCond[T](key: AttributeKey[T], vopt: Option[T], attributes: AttributeMap): AttributeMap =
|
||||||
vopt match { case Some(v) => attributes.put(key, v); case None => attributes.remove(key) }
|
vopt match { case Some(v) => attributes.put(key, v); case None => attributes.remove(key) }
|
||||||
def makeSettings(settings: Seq[Setting[_]], delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]])(implicit display: Show[ScopedKey[_]]) =
|
def makeSettings(settings: Seq[Setting[_]], delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]])(implicit display: Show[ScopedKey[_]]) =
|
||||||
translateCyclic( make(settings)(delegates, scopeLocal, display) )
|
make(settings)(delegates, scopeLocal, display)
|
||||||
|
|
||||||
def displayFull(scoped: ScopedKey[_]): String = Scope.display(scoped.scope, scoped.key.label)
|
def displayFull(scoped: ScopedKey[_]): String = Scope.display(scoped.scope, scoped.key.label)
|
||||||
def display(ref: Reference): String =
|
def display(ref: Reference): String =
|
||||||
|
|
@ -247,8 +247,6 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
val f = mapScope(g)
|
val f = mapScope(g)
|
||||||
ss.map(_ mapReferenced f)
|
ss.map(_ mapReferenced f)
|
||||||
}
|
}
|
||||||
def translateCyclic[T](f: => T): T =
|
|
||||||
try { f } catch { case c: Dag.Cyclic => throw new MessageOnlyException(c.getMessage) }
|
|
||||||
|
|
||||||
def delegates(structure: BuildStructure, scope: Scope, key: AttributeKey[_]): Seq[ScopedKey[_]] =
|
def delegates(structure: BuildStructure, scope: Scope, key: AttributeKey[_]): Seq[ScopedKey[_]] =
|
||||||
structure.delegates(scope).map(d => ScopedKey(d, key))
|
structure.delegates(scope).map(d => ScopedKey(d, key))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
object B {
|
||||||
|
val x = 3
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import sbt._
|
||||||
|
import Keys._
|
||||||
|
|
||||||
|
object Build extends Build {
|
||||||
|
|
||||||
|
lazy val root: Project = Project(
|
||||||
|
"root",
|
||||||
|
file("."),
|
||||||
|
aggregate = Seq(sub)
|
||||||
|
)
|
||||||
|
|
||||||
|
lazy val sub: Project = Project(
|
||||||
|
"sub",
|
||||||
|
file("sub"),
|
||||||
|
dependencies = Seq(root)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
object A {
|
||||||
|
def x = B.x
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
> compile
|
||||||
|
|
@ -60,6 +60,7 @@ object Dag
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
def this(value: Any) = this(value, value :: Nil, false)
|
def this(value: Any) = this(value, value :: Nil, false)
|
||||||
|
override def toString = getMessage
|
||||||
def ::(a: Any): Cyclic =
|
def ::(a: Any): Cyclic =
|
||||||
if(complete)
|
if(complete)
|
||||||
this
|
this
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue