diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 0a7e07882..937648cc0 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -474,18 +474,23 @@ private object IvySbt */ def mergeDuplicateDefinitions(dependencies: Seq[DependencyDescriptor]): Seq[DependencyDescriptor] = { - val deps = new java.util.LinkedHashMap[ModuleRevisionId, DependencyDescriptor] + // need to preserve basic order of dependencies: can't use dependencies.groupBy + val deps = new java.util.LinkedHashMap[ModuleRevisionId, List[DependencyDescriptor]] for( dd <- dependencies ) { val id = dd.getDependencyRevisionId val updated = deps get id match { - case null => dd - case v => ivyint.MergeDescriptors(v, dd) + case null => dd :: Nil + case v => dd :: v } deps.put(id, updated) } + import collection.JavaConverters._ - deps.values.asScala.toSeq + deps.values.asScala.toSeq.flatMap { dds => + val mergeable = (dds, dds.tail).zipped.forall( ivyint.MergeDescriptors.mergeable _) + if(mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds + } } /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ diff --git a/ivy/MergeDescriptors.scala b/ivy/MergeDescriptors.scala index f46f90501..e1c07c780 100644 --- a/ivy/MergeDescriptors.scala +++ b/ivy/MergeDescriptors.scala @@ -15,20 +15,24 @@ import util.extendable.ExtendableItem private[sbt] object MergeDescriptors { + def mergeable(a: DependencyDescriptor, b: DependencyDescriptor): Boolean = + a.isForce == b.isForce && + a.isChanging == b.isChanging && + a.isTransitive == b.isTransitive && + a.getParentRevisionId == b.getParentRevisionId && + a.getNamespace == b.getNamespace && { + val amrid = a.getDependencyRevisionId + val bmrid = b.getDependencyRevisionId + amrid == bmrid + } && { + val adyn = a.getDynamicConstraintDependencyRevisionId + val bdyn = b.getDynamicConstraintDependencyRevisionId + adyn == bdyn + } + def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = { - assert(a.isForce == b.isForce) - assert(a.isChanging == b.isChanging) - assert(a.isTransitive == b.isTransitive) - assert(a.getParentRevisionId == b.getParentRevisionId) - val amrid = a.getDependencyRevisionId - val bmrid = b.getDependencyRevisionId - assert(amrid == bmrid) - val adyn = a.getDynamicConstraintDependencyRevisionId - val bdyn = b.getDynamicConstraintDependencyRevisionId - assert(adyn == bdyn) - assert(a.getNamespace == b.getNamespace) - + assert(mergeable(a,b)) new MergedDescriptors(a,b) } }