From e17ab305aede0147d4f9c95cc868d1ba4ca2e2fe Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 12 Dec 2014 17:00:35 -0500 Subject: [PATCH 1/3] Fixes minor mistake in #1748 --- main/src/main/scala/sbt/Defaults.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index b60c4fce4..b6de92e84 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1337,7 +1337,7 @@ object Classpaths { case Some(x) if uc0.logging == Default => uc0.copy(logging = DownloadOnly) case _ => uc0 } - cachedUpdate(s.cacheDirectory / updateCacheName.value, show, ivyModule.value, uc0, transform, + cachedUpdate(s.cacheDirectory / updateCacheName.value, show, ivyModule.value, uc, transform, skip = (skip in update).value, force = isRoot, depsUpdated = depsUpdated, uwConfig = uwConfig, logicalClock = logicalClock, depDir = Some(depDir), log = s.log) } From 40e5f7538ae22b241ebb0826da387054654035c9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 12 Dec 2014 17:46:19 -0500 Subject: [PATCH 2/3] Fixes #1615. Move the invocation of eviction warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This moves the invocation of eviction warning so it’s called only when actual ivy update is being performed. --- ivy/src/main/scala/sbt/EvictionWarning.scala | 2 ++ main/src/main/scala/sbt/Defaults.scala | 22 ++++++++++++-------- notes/0.13.8/eviction-warning-fix.markdown | 13 ++++++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 notes/0.13.8/eviction-warning-fix.markdown diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index 7279b77da..38d626a86 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -41,6 +41,8 @@ final class EvictionWarningOptions private[sbt] ( } object EvictionWarningOptions { + def empty: EvictionWarningOptions = + new EvictionWarningOptions(Vector(), false, false, false, false, defaultGuess) def default: EvictionWarningOptions = new EvictionWarningOptions(Vector(Compile), true, true, false, false, defaultGuess) def full: EvictionWarningOptions = diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index b6de92e84..461b9b21a 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1151,13 +1151,9 @@ object Classpaths { unresolvedWarningConfiguration in update := UnresolvedWarningConfiguration(dependencyPositions.value), update <<= updateTask tag (Tags.Update, Tags.Network), update := { - import ShowLines._ val report = update.value val log = streams.value.log ConflictWarning(conflictWarning.value, report, log) - val ewo = (evictionWarningOptions in update).value - val ew = EvictionWarning(ivyModule.value, ewo, report, log) - ew.lines foreach { log.warn(_) } report }, evictionWarningOptions in evicted := EvictionWarningOptions.full, @@ -1337,33 +1333,41 @@ object Classpaths { case Some(x) if uc0.logging == Default => uc0.copy(logging = DownloadOnly) case _ => uc0 } + val ewo = + if (executionRoots.value exists { _.key == evicted.key }) EvictionWarningOptions.empty + else (evictionWarningOptions in update).value cachedUpdate(s.cacheDirectory / updateCacheName.value, show, ivyModule.value, uc, transform, skip = (skip in update).value, force = isRoot, depsUpdated = depsUpdated, - uwConfig = uwConfig, logicalClock = logicalClock, depDir = Some(depDir), log = s.log) + uwConfig = uwConfig, logicalClock = logicalClock, depDir = Some(depDir), + ewo = ewo, log = s.log) } @deprecated("Use cachedUpdate with the variant that takes unresolvedHandler instead.", "0.13.6") def cachedUpdate(cacheFile: File, label: String, module: IvySbt#Module, config: UpdateConfiguration, transform: UpdateReport => UpdateReport, skip: Boolean, force: Boolean, depsUpdated: Boolean, log: Logger): UpdateReport = cachedUpdate(cacheFile, label, module, config, transform, skip, force, depsUpdated, - UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) + UnresolvedWarningConfiguration(), LogicalClock.unknown, None, EvictionWarningOptions.empty, log) private[sbt] def cachedUpdate(cacheFile: File, label: String, module: IvySbt#Module, config: UpdateConfiguration, transform: UpdateReport => UpdateReport, skip: Boolean, force: Boolean, depsUpdated: Boolean, - uwConfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger): UpdateReport = + uwConfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], + ewo: EvictionWarningOptions, log: Logger): UpdateReport = { implicit val updateCache = updateIC type In = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil def work = (_: In) match { case conf :+: settings :+: config :+: HNil => + import ShowLines._ log.info("Updating " + label + "...") val r = IvyActions.updateEither(module, config, uwConfig, logicalClock, depDir, log) match { case Right(ur) => ur case Left(uw) => - import ShowLines._ uw.lines foreach { log.warn(_) } throw uw.resolveException } log.info("Done updating.") - transform(r) + val result = transform(r) + val ew = EvictionWarning(module, ewo, result, log) + ew.lines foreach { log.warn(_) } + result } def uptodate(inChanged: Boolean, out: UpdateReport): Boolean = !force && diff --git a/notes/0.13.8/eviction-warning-fix.markdown b/notes/0.13.8/eviction-warning-fix.markdown new file mode 100644 index 000000000..ee54e80a8 --- /dev/null +++ b/notes/0.13.8/eviction-warning-fix.markdown @@ -0,0 +1,13 @@ + [@cunei]: https://github.com/cunei + [@eed3si9n]: https://github.com/eed3si9n + [@gkossakowski]: https://github.com/gkossakowski + [@jsuereth]: https://github.com/jsuereth + [1615]: https://github.com/sbt/sbt/issues/1615 + +### Fixes with compatibility implications + +### Improvements + +### Bug fixes + +- Fixes eviction warning being too noisy. [#1615][1615] by [@eed3si9n][@eed3si9n] From 46f56851d44ad351e99206158a3a85f9d20ab943 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 12 Dec 2014 23:30:05 -0500 Subject: [PATCH 3/3] 'evicted' task to display all evictions --- ivy/src/main/scala/sbt/EvictionWarning.scala | 41 ++++++++++++++++++-- main/src/main/scala/sbt/Defaults.scala | 2 + notes/0.13.8/eviction-warning-fix.markdown | 2 + 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index 38d626a86..0e0234de5 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -9,6 +9,7 @@ final class EvictionWarningOptions private[sbt] ( val warnScalaVersionEviction: Boolean, val warnDirectEvictions: Boolean, val warnTransitiveEvictions: Boolean, + val infoAllEvictions: Boolean, val showCallers: Boolean, val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]) { private[sbt] def configStrings = configurations map { _.name } @@ -21,6 +22,8 @@ final class EvictionWarningOptions private[sbt] ( copy(warnDirectEvictions = warnDirectEvictions) def withWarnTransitiveEvictions(warnTransitiveEvictions: Boolean): EvictionWarningOptions = copy(warnTransitiveEvictions = warnTransitiveEvictions) + def withInfoAllEvictions(infoAllEvictions: Boolean): EvictionWarningOptions = + copy(infoAllEvictions = infoAllEvictions) def withShowCallers(showCallers: Boolean): EvictionWarningOptions = copy(showCallers = showCallers) def withGuessCompatible(guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]): EvictionWarningOptions = @@ -30,23 +33,25 @@ final class EvictionWarningOptions private[sbt] ( warnScalaVersionEviction: Boolean = warnScalaVersionEviction, warnDirectEvictions: Boolean = warnDirectEvictions, warnTransitiveEvictions: Boolean = warnTransitiveEvictions, + infoAllEvictions: Boolean = infoAllEvictions, showCallers: Boolean = showCallers, guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessCompatible): EvictionWarningOptions = new EvictionWarningOptions(configurations = configurations, warnScalaVersionEviction = warnScalaVersionEviction, warnDirectEvictions = warnDirectEvictions, warnTransitiveEvictions = warnTransitiveEvictions, + infoAllEvictions = infoAllEvictions, showCallers = showCallers, guessCompatible = guessCompatible) } object EvictionWarningOptions { def empty: EvictionWarningOptions = - new EvictionWarningOptions(Vector(), false, false, false, false, defaultGuess) + new EvictionWarningOptions(Vector(), false, false, false, false, false, defaultGuess) def default: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), true, true, false, false, defaultGuess) + new EvictionWarningOptions(Vector(Compile), true, true, false, false, false, defaultGuess) def full: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), true, true, true, true, defaultGuess) + new EvictionWarningOptions(Vector(Compile), true, true, true, true, true, defaultGuess) lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse @@ -80,6 +85,18 @@ final class EvictionPair private[sbt] ( val showCallers: Boolean) { override def toString: String = EvictionPair.evictionPairLines.showLines(this).mkString + override def equals(o: Any): Boolean = o match { + case o: EvictionPair => + (this.organization == o.organization) && + (this.name == o.name) + case _ => false + } + override def hashCode: Int = { + var hash = 1 + hash = hash * 31 + this.organization.## + hash = hash * 31 + this.name.## + hash + } } object EvictionPair { @@ -107,6 +124,7 @@ final class EvictionWarning private[sbt] ( val transitiveEvictions: Seq[EvictionPair], val allEvictions: Seq[EvictionPair]) { def reportedEvictions: Seq[EvictionPair] = scalaEvictions ++ directEvictions ++ transitiveEvictions + private[sbt] def infoAllTheThings: List[String] = EvictionWarning.infoAllTheThings(this) } object EvictionWarning { @@ -203,4 +221,21 @@ object EvictionWarning { out.toList } + + private[sbt] def infoAllTheThings(a: EvictionWarning): List[String] = + if (a.options.infoAllEvictions) { + import ShowLines._ + val evo = a.options + val out: mutable.ListBuffer[String] = mutable.ListBuffer() + a.allEvictions foreach { ev => + if ((a.scalaEvictions contains ev) && evo.warnScalaVersionEviction) () + else if ((a.directEvictions contains ev) && evo.warnDirectEvictions) () + else if ((a.transitiveEvictions contains ev) && evo.warnTransitiveEvictions) () + else { + out ++= ev.lines + } + } + if (out.isEmpty) Nil + else List("Here are other libraries that were evicted:") ::: out.toList + } else Nil } diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 461b9b21a..06d489773 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1163,6 +1163,7 @@ object Classpaths { val log = streams.value.log val ew = EvictionWarning(ivyModule.value, (evictionWarningOptions in evicted).value, report, log) ew.lines foreach { log.warn(_) } + ew.infoAllTheThings foreach { log.info(_) } ew }, classifiersModule in updateClassifiers := { @@ -1367,6 +1368,7 @@ object Classpaths { val result = transform(r) val ew = EvictionWarning(module, ewo, result, log) ew.lines foreach { log.warn(_) } + ew.infoAllTheThings foreach { log.info(_) } result } def uptodate(inChanged: Boolean, out: UpdateReport): Boolean = diff --git a/notes/0.13.8/eviction-warning-fix.markdown b/notes/0.13.8/eviction-warning-fix.markdown index ee54e80a8..a0c2b2818 100644 --- a/notes/0.13.8/eviction-warning-fix.markdown +++ b/notes/0.13.8/eviction-warning-fix.markdown @@ -8,6 +8,8 @@ ### Improvements +- `evicted` will display all evictions (including the ones not suspected of binary incompatibility). [#1615][1615] by [@eed3si9n][@eed3si9n] + ### Bug fixes - Fixes eviction warning being too noisy. [#1615][1615] by [@eed3si9n][@eed3si9n]