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] =
|
||||
{
|
||||
val full = Dag.topologicalSort(base)(getDependencies(structure, classpath, aggregate))
|
||||
if(includeRoot) full else full.dropRight(1)
|
||||
def tdeps(enabled: Boolean, f: ProjectRef => Seq[ProjectRef]): Seq[ProjectRef] =
|
||||
{
|
||||
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] =
|
||||
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 =
|
||||
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[_]]) =
|
||||
translateCyclic( make(settings)(delegates, scopeLocal, display) )
|
||||
make(settings)(delegates, scopeLocal, display)
|
||||
|
||||
def displayFull(scoped: ScopedKey[_]): String = Scope.display(scoped.scope, scoped.key.label)
|
||||
def display(ref: Reference): String =
|
||||
|
|
@ -247,8 +247,6 @@ object Project extends Init[Scope] with ProjectExtra
|
|||
val f = mapScope(g)
|
||||
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[_]] =
|
||||
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)
|
||||
override def toString = getMessage
|
||||
def ::(a: Any): Cyclic =
|
||||
if(complete)
|
||||
this
|
||||
|
|
|
|||
Loading…
Reference in New Issue