Merge pull request #1634 from sbt/fix/1634

A library is missing from dependencyClasspath if it's added to libraryDependencies twice in ascending order
This commit is contained in:
Josh Suereth 2014-12-15 16:05:57 -05:00
commit 1d68855285
3 changed files with 55 additions and 0 deletions

View File

@ -527,6 +527,29 @@ private[sbt] object IvySbt {
parser
}
def inconsistentDuplicateWarning(moduleID: DefaultModuleDescriptor): List[String] =
{
import IvyRetrieve.toModuleID
val dds = moduleID.getDependencies
inconsistentDuplicateWarning(dds map { dd => toModuleID(dd.getDependencyRevisionId) })
}
def inconsistentDuplicateWarning(dependencies: Seq[ModuleID]): List[String] =
{
val warningHeader = "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:"
val out: mutable.ListBuffer[String] = mutable.ListBuffer()
(dependencies groupBy { dep => (dep.organization, dep.name) }) foreach {
case (k, vs) if vs.size > 1 =>
val v0 = vs.head
(vs find { _.revision != v0.revision }) foreach { v =>
out += s" * ${v0.organization}:${v0.name}:(" + (vs map { _.revision }).mkString(", ") + ")"
}
case _ => ()
}
if (out.isEmpty) Nil
else warningHeader :: out.toList
}
/** This method is used to add inline dependencies to the provided module. */
def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Seq[ModuleID], parser: CustomXmlParser.CustomParser) {
val converted = dependencies map { dependency => convertDependency(moduleID, dependency, parser) }

View File

@ -166,6 +166,8 @@ object IvyActions {
case (ivy, md, default) if module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined =>
ivy.getResolveEngine match {
case x: CachedResolutionResolveEngine =>
val iw = IvySbt.inconsistentDuplicateWarning(md)
iw foreach { log.warn(_) }
val resolveOptions = new ResolveOptions
val resolveId = ResolveOptions.getDefaultResolveId(md)
resolveOptions.setResolveId(resolveId)
@ -181,6 +183,8 @@ object IvyActions {
}
}
case (ivy, md, default) =>
val iw = IvySbt.inconsistentDuplicateWarning(md)
iw foreach { log.warn(_) }
val (report, err) = resolve(configuration.logging)(ivy, md, default)
err match {
case Some(x) if !configuration.missingOk =>

View File

@ -0,0 +1,28 @@
package sbt
import org.specs2._
class InconsistentDuplicateSpec extends Specification {
def is = s2"""
This is a specification to check the inconsistent duplicate warnings
Duplicate with different version should
be warned $warn1
Duplicate with same version should
not be warned $nodupe1
"""
def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary
def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary
def akkaActor230Test = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("test")) cross CrossVersion.binary
def warn1 =
IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) must_==
List("Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:",
" * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)")
def nodupe1 =
IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) must_== Nil
}