From a50f96c7c46d59cc8c1a5d321f8269da1f89e0cf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 21 May 2017 13:18:11 -0400 Subject: [PATCH 1/3] change EvictionWarningOptions.default Fixes sbt/sbt#3171 change EvictionWarningOptions.default to include transitive evictions and caller info. --- .../librarymanagement/EvictionWarning.scala | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index eff181a25..1dd049e5b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -58,11 +58,29 @@ final class EvictionWarningOptions private[sbt] ( object EvictionWarningOptions { def empty: EvictionWarningOptions = - new EvictionWarningOptions(Vector(), false, false, false, false, false, defaultGuess) + new EvictionWarningOptions(Vector(), + warnScalaVersionEviction = false, + warnDirectEvictions = false, + warnTransitiveEvictions = false, + infoAllEvictions = false, + showCallers = false, + defaultGuess) def default: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), true, true, false, false, false, defaultGuess) + new EvictionWarningOptions(Vector(Compile), + warnScalaVersionEviction = true, + warnDirectEvictions = true, + warnTransitiveEvictions = true, + infoAllEvictions = false, + showCallers = true, + defaultGuess) def full: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), true, true, true, true, true, defaultGuess) + new EvictionWarningOptions(Vector(Compile), + warnScalaVersionEviction = true, + warnDirectEvictions = true, + warnTransitiveEvictions = true, + infoAllEvictions = true, + showCallers = true, + defaultGuess) lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse From 182a07402acf05261fa4b2d5b7ca5cb54f0864f4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 21 May 2017 13:59:07 -0400 Subject: [PATCH 2/3] update EvictionWarningSpec --- .../librarymanagement/EvictionWarning.scala | 24 +++++---- .../src/test/scala/EvictionWarningSpec.scala | 49 ++++++------------- 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 1dd049e5b..b0e22ce47 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -59,28 +59,32 @@ final class EvictionWarningOptions private[sbt] ( object EvictionWarningOptions { def empty: EvictionWarningOptions = new EvictionWarningOptions(Vector(), - warnScalaVersionEviction = false, - warnDirectEvictions = false, - warnTransitiveEvictions = false, - infoAllEvictions = false, - showCallers = false, - defaultGuess) + warnScalaVersionEviction = false, + warnDirectEvictions = false, + warnTransitiveEvictions = false, + infoAllEvictions = false, + showCallers = false, + defaultGuess) def default: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), + new EvictionWarningOptions( + Vector(Compile), warnScalaVersionEviction = true, warnDirectEvictions = true, warnTransitiveEvictions = true, infoAllEvictions = false, showCallers = true, - defaultGuess) + defaultGuess + ) def full: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), + new EvictionWarningOptions( + Vector(Compile), warnScalaVersionEviction = true, warnDirectEvictions = true, warnTransitiveEvictions = true, infoAllEvictions = true, showCallers = true, - defaultGuess) + defaultGuess + ) lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 8daf2277a..5dd74fb6d 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -26,8 +26,7 @@ class EvictionWarningSpec extends BaseIvySpecification { it should "print out message about the eviction" in javaLibNoWarn2() """Including two (suspect) transitively binary incompatible Java libraries to direct dependencies - """ should "be not detected as eviction" in javaLibTransitiveWarn1() - it should "be detected if it's enabled" in javaLibTransitiveWarn2() + """ should "be detected as eviction" in javaLibTransitiveWarn2() //it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3() @@ -40,8 +39,7 @@ class EvictionWarningSpec extends BaseIvySpecification { it should "print out message about the eviction" in scalaLibNoWarn2() """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies - """ should "be not detected as eviction" in scalaLibTransitiveWarn1() - it should "be detected if it's enabled" in scalaLibTransitiveWarn2() + """ should "be detected as eviction" in scalaLibTransitiveWarn2() it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() def akkaActor214 = @@ -89,7 +87,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn3() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe + EvictionWarning(m, defaultOptions.withShowCallers(false), report, log).lines shouldBe List( "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3", @@ -102,7 +100,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn4() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)", @@ -134,7 +132,12 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn2() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnDirectEvictions(false), report, log).reportedEvictions should have size (0) + EvictionWarning(m, + defaultOptions + .withWarnDirectEvictions(false) + .withWarnTransitiveEvictions(false), + report, + log).reportedEvictions should have size (0) } def javaLibWarn3() = { @@ -144,8 +147,7 @@ class EvictionWarningSpec extends BaseIvySpecification { List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4", - "Run 'evicted' to see detailed eviction warnings" + "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)" ) } @@ -176,25 +178,16 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibTransitiveDeps = Vector(unfilteredUploads080, bnfparser10) - def javaLibTransitiveWarn1() = { - val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) - } - def javaLibTransitiveWarn2() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size (1) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) } def javaLibTransitiveWarn3() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, - defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), - report, - log).lines shouldBe + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", @@ -217,8 +210,7 @@ class EvictionWarningSpec extends BaseIvySpecification { List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", - "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4", - "Run 'evicted' to see detailed eviction warnings" + "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.example:foo:0.1.0)" ) } @@ -238,25 +230,16 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234) - def scalaLibTransitiveWarn1() = { - val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) - } - def scalaLibTransitiveWarn2() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size (1) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) } def scalaLibTransitiveWarn3() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, - defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), - report, - log).lines shouldBe + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", From 182b50a12b990ed58f1b93b629354623ddd12448 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 23 May 2017 02:42:59 -0400 Subject: [PATCH 3/3] Improve the eviction warning presentation. Fixes sbt/sbt#2699 Before: [warn] There may be incompatibilities among your library dependencies. [warn] Here are some of the libraries that were evicted: [warn] * com.google.code.findbugs:jsr305:2.0.1 -> 3.0.0 [warn] Run 'evicted' to see detailed eviction warnings After: [warn] Found version conflict(s) in library dependencies; some are suspected to be binary incompatible: [warn] [warn] * com.typesafe.akka:akka-actor_2.12:2.5.0 is selected over 2.4.17 [warn] +- de.heikoseeberger:akka-log4j_2.12:1.4.0 (depends on 2.5.0) [warn] +- com.typesafe.akka:akka-parsing_2.12:10.0.6 (depends on 2.4.17) [warn] +- com.typesafe.akka:akka-stream_2.12:2.4.17 () (depends on 2.4.17) [warn] [warn] Run 'evicted' to see detailed eviction warnings --- .../librarymanagement/EvictionWarning.scala | 37 ++++++++------ .../src/test/scala/EvictionWarningSpec.scala | 49 +++++++++++++------ 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index b0e22ce47..66e9d3185 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -143,17 +143,24 @@ final class EvictionPair private[sbt] ( object EvictionPair { implicit val evictionPairLines: ShowLines[EvictionPair] = ShowLines { a: EvictionPair => val revs = a.evicteds map { _.module.revision } - val revsStr = if (revs.size <= 1) revs.mkString else "(" + revs.mkString(", ") + ")" - val winnerRev = (a.winner map { r => - val callers: String = - if (a.showCallers) - r.callers match { - case Seq() => "" - case cs => (cs map { _.caller.toString }).mkString(" (caller: ", ", ", ")") - } else "" - r.module.revision + callers - }) map { " -> " + _ } getOrElse "" - Seq(s"\t* ${a.organization}:${a.name}:${revsStr}$winnerRev") + val revsStr = if (revs.size <= 1) revs.mkString else "{" + revs.mkString(", ") + "}" + val seen: mutable.Set[ModuleID] = mutable.Set() + val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => + val rev = r.module.revision + r.callers.toList flatMap { caller => + if (seen(caller.caller)) Nil + else { + seen += caller.caller + List(f"\t +- ${caller}%-50s (depends on $rev)") + } + } + } + val winnerRev = a.winner match { + case Some(r) => s":${r.module.revision} is selected over ${revsStr}" + case _ => " is evicted completely" + } + val title = s"\t* ${a.organization}:${a.name}$winnerRev" + title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") } } @@ -285,13 +292,13 @@ object EvictionWarning { } if (a.directEvictions.nonEmpty || a.transitiveEvictions.nonEmpty) { - out += "There may be incompatibilities among your library dependencies." - out += "Here are some of the libraries that were evicted:" + out += "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" + out += "" out ++= (a.directEvictions flatMap { _.lines }) out ++= (a.transitiveEvictions flatMap { _.lines }) } - if (a.allEvictions.nonEmpty && a.reportedEvictions.nonEmpty && !a.options.showCallers) { + if (a.allEvictions.nonEmpty && a.reportedEvictions.nonEmpty) { out += "Run 'evicted' to see detailed eviction warnings" } @@ -312,6 +319,6 @@ object EvictionWarning { } } if (out.isEmpty) Nil - else List("Here are other libraries that were evicted:") ::: out.toList + else List("Here are other depedency conflicts that were resolved:", "") ::: out.toList } else Nil } diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 5dd74fb6d..1601962d9 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -90,7 +90,8 @@ class EvictionWarningSpec extends BaseIvySpecification { EvictionWarning(m, defaultOptions.withShowCallers(false), report, log).lines shouldBe List( "Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3", + "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", + "", "To force scalaVersion, add the following:", "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }", "Run 'evicted' to see detailed eviction warnings" @@ -103,9 +104,13 @@ class EvictionWarningSpec extends BaseIvySpecification { EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( "Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)", + "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", + "\t +- com.typesafe.akka:akka-actor_2.10:2.3.0 (depends on 2.10.3)", + "\t +- com.example:foo:0.1.0 (depends on 2.10.2)", + "", "To force scalaVersion, add the following:", - "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }" + "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }", + "Run 'evicted' to see detailed eviction warnings" ) } @@ -145,9 +150,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)" + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* commons-io:commons-io:2.4 is selected over 1.4", + "\t +- com.example:foo:0.1.0 (depends on 1.4)", + "", + "Run 'evicted' to see detailed eviction warnings" ) } @@ -156,9 +164,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)" + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* commons-io:commons-io:2.4 is selected over 1.4", + "\t +- com.example:foo:0.1.0 (depends on 1.4)", + "", + "Run 'evicted' to see detailed eviction warnings" ) } @@ -208,9 +219,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Here are some of the libraries that were evicted:", - "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.example:foo:0.1.0)" + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", + "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", + "", + "Run 'evicted' to see detailed eviction warnings" ) } @@ -241,9 +255,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Here are some of the libraries that were evicted:", - "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.typesafe.akka:akka-remote_2.10:2.3.4, org.w3:banana-sesame_2.10:0.4, org.w3:banana-rdf_2.10:0.4)" + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", + "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", + "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", + "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", + "", + "Run 'evicted' to see detailed eviction warnings" ) } }