From de4719a577b5117d035b331944e02721ff69bf19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Mickevi=C4=8Dius?= Date: Tue, 22 May 2018 10:34:02 +0300 Subject: [PATCH 1/6] Add support for versions with less segments (#212) --- project/Build.scala | 1 + .../tools/mima/plugin/MimaPlugin.scala | 12 ++- .../typesafe/tools/mima/plugin/SbtMima.scala | 77 ++++++++----------- .../mima/plugin/ProblemReportingSpec.scala | 61 +++++++++++++++ 4 files changed, 101 insertions(+), 50 deletions(-) create mode 100644 sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala diff --git a/project/Build.scala b/project/Build.scala index 31bb0e4d..0ce616fb 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -190,6 +190,7 @@ object MimaBuild { (sbtBinaryVersion in pluginCrossBuild).value, (scalaBinaryVersion in update).value ), + libraryDependencies += scalatest, scriptedLaunchOpts := scriptedLaunchOpts.value :+ "-Dplugin.version=" + version.value, scriptedBufferLog := false, // Scripted locally publishes sbt plugin and then runs test projects with locally published version. diff --git a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/MimaPlugin.scala b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/MimaPlugin.scala index df82c79d..ef9de915 100644 --- a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/MimaPlugin.scala +++ b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/MimaPlugin.scala @@ -23,8 +23,7 @@ object MimaPlugin extends AutoPlugin { mimaBackwardIssueFilters := SbtMima.issueFiltersFromFiles(mimaFiltersDirectory.value, "\\.(?:backward[s]?|both)\\.excludes".r, streams.value), mimaForwardIssueFilters := SbtMima.issueFiltersFromFiles(mimaFiltersDirectory.value, "\\.(?:forward[s]?|both)\\.excludes".r, streams.value), mimaFindBinaryIssues := { - val taskStreams = streams.value - val log = taskStreams.log + val log = new SbtLogger(streams.value) val projectName = name.value val previousClassfiles = mimaPreviousClassfiles.value val currentClassfiles = mimaCurrentClassfiles.value @@ -37,14 +36,13 @@ object MimaPlugin extends AutoPlugin { else { previousClassfiles.map { case (moduleId, file) => - val problems = SbtMima.runMima(file, currentClassfiles, cp, checkDirection, taskStreams) + val problems = SbtMima.runMima(file, currentClassfiles, cp, checkDirection, log) (moduleId, (problems._1, problems._2)) } } }, mimaReportBinaryIssues := { - val taskStreams = streams.value - val log = taskStreams.log + val log = new SbtLogger(streams.value) val projectName = name.value val currentClassfiles = mimaCurrentClassfiles.value val cp = (fullClasspath in mimaFindBinaryIssues).value @@ -65,7 +63,7 @@ object MimaPlugin extends AutoPlugin { currentClassfiles, cp, checkDirection, - taskStreams + log ) SbtMima.reportModuleErrors( moduleId, @@ -74,7 +72,7 @@ object MimaPlugin extends AutoPlugin { binaryIssueFilters, backwardIssueFilters, forwardIssueFilters, - taskStreams, + log, projectName) } } diff --git a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala index 3db11112..116291ff 100644 --- a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala +++ b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala @@ -24,42 +24,29 @@ object SbtMima { val x = sbt.Keys.fullClasspath /** Creates a new MiMaLib object to run analysis. */ - private def makeMima(cp: sbt.Keys.Classpath, s: TaskStreams): lib.MiMaLib = { + private def makeMima(cp: sbt.Keys.Classpath, log: Logging): lib.MiMaLib = { // TODO: Fix MiMa so we don't have to hack this bit in. core.Config.setup("sbt-mima-plugin", Array.empty) val cpstring = cp map (_.data.getAbsolutePath()) mkString System.getProperty("path.separator") val classpath = com.typesafe.tools.mima.core.reporterClassPath(cpstring) - new lib.MiMaLib(classpath, new SbtLogger(s)) + new lib.MiMaLib(classpath, log) } /** Runs MiMa and returns a two lists of potential binary incompatibilities, the first for backward compatibility checking, and the second for forward checking. */ def runMima(prev: File, curr: File, cp: sbt.Keys.Classpath, - dir: String, s: TaskStreams): (List[core.Problem], List[core.Problem]) = { + dir: String, log: Logging): (List[core.Problem], List[core.Problem]) = { // MiMaLib collects problems to a mutable buffer, therefore we need a new instance every time (dir match { - case "backward" | "backwards" | "both" => makeMima(cp, s).collectProblems(prev.getAbsolutePath, curr.getAbsolutePath) + case "backward" | "backwards" | "both" => makeMima(cp, log).collectProblems(prev.getAbsolutePath, curr.getAbsolutePath) case _ => Nil }, dir match { - case "forward" | "forwards" | "both" => makeMima(cp, s).collectProblems(curr.getAbsolutePath, prev.getAbsolutePath) + case "forward" | "forwards" | "both" => makeMima(cp, log).collectProblems(curr.getAbsolutePath, prev.getAbsolutePath) case _ => Nil }) } - /** Reports binary compatibility errors. - * @param failOnProblem if true, fails the build on binary compatibility errors. - */ - def reportErrors(problemsInFiles: Map[ModuleID, (List[core.Problem], List[core.Problem])], - failOnProblem: Boolean, - filters: Seq[core.ProblemFilter], - backwardFilters: Map[String, Seq[core.ProblemFilter]], - forwardFilters: Map[String, Seq[core.ProblemFilter]], - s: TaskStreams, projectName: String): Unit = - problemsInFiles foreach { case (module, (backward, forward)) => - reportModuleErrors(module, backward, forward, failOnProblem, filters, backwardFilters, forwardFilters, s, projectName) - } - /** Reports binary compatibility errors for a module. * @param failOnProblem if true, fails the build on binary compatibility errors. */ @@ -70,48 +57,52 @@ object SbtMima { filters: Seq[core.ProblemFilter], backwardFilters: Map[String, Seq[core.ProblemFilter]], forwardFilters: Map[String, Seq[core.ProblemFilter]], - s: TaskStreams, projectName: String): Unit = { + log: Logging, projectName: String): Unit = { // filters * found is n-squared, it's fixable in principle by special-casing known // filter types or something, not worth it most likely... + val backErrors = backward filter isReported(module, filters, backwardFilters)(log, projectName) + val forwErrors = forward filter isReported(module, filters, forwardFilters)(log, projectName) + + val filteredCount = backward.size + forward.size - backErrors.size - forwErrors.size + val filteredNote = if (filteredCount > 0) " (filtered " + filteredCount + ")" else "" + + // TODO - Line wrapping an other magikz + def prettyPrint(p: core.Problem, affected: String): String = { + " * " + p.description(affected) + p.howToFilter.map("\n filter with: " + _).getOrElse("") + } + + log.info(s"$projectName: found ${backErrors.size+forwErrors.size} potential binary incompatibilities while checking against $module $filteredNote") + ((backErrors map {p: core.Problem => prettyPrint(p, "current")}) ++ + (forwErrors map {p: core.Problem => prettyPrint(p, "other")})) foreach { log.info } + if (failOnProblem && (backErrors.nonEmpty || forwErrors.nonEmpty)) sys.error(projectName + ": Binary compatibility check failed!") + } + + private[mima] def isReported(module: ModuleID, filters: Seq[core.ProblemFilter], versionedFilters: Map[String, Seq[core.ProblemFilter]])(log: Logging, projectName: String)(problem: core.Problem) = { + // version string "x.y.z" is converted to an Int tuple (x, y, z) for comparison val versionOrdering = Ordering[(Int, Int, Int)].on { version: String => - val ModuleVersion = """(\d+)\.(\d+)\.(.*)""".r - val ModuleVersion(epoch, major, minor) = version + val ModuleVersion = """(\d+)\.?(\d+)?\.?(.*)?""".r + val (epoch, major, minor) = version match { + case ModuleVersion(e, m, mi) => (e, m, mi) + case ModuleVersion(e, m, null) => (e, m, "0") + case ModuleVersion(e, null, null) => (e, "0", "0") + } val toNumeric = (revision: String) => Try(revision.replace("x", Short.MaxValue.toString).filter(_.isDigit).toInt).getOrElse(0) (toNumeric(epoch), toNumeric(major), toNumeric(minor)) } - def isReported(module: ModuleID, verionedFilters: Map[String, Seq[core.ProblemFilter]])(problem: core.Problem) = (verionedFilters.collect { + (versionedFilters.collect { // get all filters that apply to given module version or any version after it - case f @ (version, filters) if versionOrdering.gteq(version, module.revision) => filters + case f @ (version, versionFilters) if versionOrdering.gteq(version, module.revision) => versionFilters }.flatten ++ filters).forall { f => if (f(problem)) { true } else { - s.log.debug(projectName + ": filtered out: " + problem.description + "\n filtered by: " + f) + log.debugLog(projectName + ": filtered out: " + problem.description + "\n filtered by: " + f) false } } - - val backErrors = backward filter isReported(module, backwardFilters) - val forwErrors = forward filter isReported(module, forwardFilters) - - val filteredCount = backward.size + forward.size - backErrors.size - forwErrors.size - val filteredNote = if (filteredCount > 0) " (filtered " + filteredCount + ")" else "" - - // TODO - Line wrapping an other magikz - def prettyPrint(p: core.Problem, affected: String): String = { - " * " + p.description(affected) + p.howToFilter.map("\n filter with: " + _).getOrElse("") - } - - s.log.info(s"$projectName: found ${backErrors.size+forwErrors.size} potential binary incompatibilities while checking against $module $filteredNote") - ((backErrors map {p: core.Problem => prettyPrint(p, "current")}) ++ - (forwErrors map {p: core.Problem => prettyPrint(p, "other")})) foreach { p => - if (failOnProblem) s.log.error(p) - else s.log.warn(p) - } - if (failOnProblem && (backErrors.nonEmpty || forwErrors.nonEmpty)) sys.error(projectName + ": Binary compatibility check failed!") } /** Resolves an artifact representing the previous abstract binary interface diff --git a/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala b/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala new file mode 100644 index 00000000..9d775abf --- /dev/null +++ b/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala @@ -0,0 +1,61 @@ +package com.typesafe.tools.mima.plugin + +import com.typesafe.tools.mima.core.util.log.Logging +import com.typesafe.tools.mima.core._ +import sbt._ +import org.scalatest.{Matchers, WordSpec} + +class ProblemReportingSpec extends WordSpec with Matchers { + import ProblemReportingSpec._ + + "problem" should { + "be reported when there are no filters" in { + isReported("0.0.1", Seq.empty) shouldBe true + } + + "not be reported when filtered out by general filters" in { + isReported("0.0.1", Seq(AllMatchingFilter)) shouldBe false + } + + "not be reported when filtered out by versioned filters" in { + isReported("0.0.1", Map("0.0.1" -> Seq(AllMatchingFilter))) shouldBe false + } + + "not be reported when filtered out by versioned wildcard filters" in { + isReported("0.0.1", Map("0.0.x" -> Seq(AllMatchingFilter))) shouldBe false + } + + "not be reported when filter version does not have patch segment" in { + isReported("0.1", Map("0.1" -> Seq(AllMatchingFilter))) shouldBe false + } + + "not be reported when filter version is only epoch" in { + isReported("1", Map("1" -> Seq(AllMatchingFilter))) shouldBe false + } + + "not be reported when filter version has less segments than module version" in { + isReported("0.1.0", Map("0.1" -> Seq(AllMatchingFilter))) shouldBe false + } + + "not be reported when filter version has more segments than module version" in { + isReported("0.1", Map("0.1.0" -> Seq(AllMatchingFilter))) shouldBe false + } + } + + private def isReported(moduleVersion: String, filters: Seq[ProblemFilter]) = + SbtMima.isReported("test" % "module" % moduleVersion, filters, Map.empty)(NoOpLogger, "test")(MissingFieldProblem(NoMemberInfo)) + private def isReported(moduleVersion: String, versionedFilters: Map[String, Seq[ProblemFilter]]) = + SbtMima.isReported("test" % "module" % moduleVersion, Seq.empty, versionedFilters)(NoOpLogger, "test")(MissingFieldProblem(NoMemberInfo)) + +} + +object ProblemReportingSpec { + final val NoOpLogger = new Logging { + override def info(str: String): Unit = () + override def debugLog(str: String): Unit = () + } + + final val NoMemberInfo = new MemberInfo(NoClass, "", 0, "") + + final val AllMatchingFilter = (_: Problem) => false +} From 00a11e1b6d2d7a7f97be168b6a031f3a9cac87b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Mickevi=C4=8Dius?= Date: Tue, 22 May 2018 11:40:54 +0300 Subject: [PATCH 2/6] Add error loglevel to mima logger --- .../com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala | 3 ++- .../scala/com/typesafe/tools/mima/core/util/log/Logging.scala | 1 + .../main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala | 3 ++- .../com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala b/core/src/main/scala/com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala index 6a759366..6d6e5087 100644 --- a/core/src/main/scala/com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala +++ b/core/src/main/scala/com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala @@ -5,4 +5,5 @@ import com.typesafe.tools.mima.core.Config object ConsoleLogging extends Logging { def info(str: String) = if (Config.verbose) println(str) def debugLog(str: String) = if (Config.debug) println(str) -} \ No newline at end of file + def error(str: String) = Console.err.println(str) +} diff --git a/core/src/main/scala/com/typesafe/tools/mima/core/util/log/Logging.scala b/core/src/main/scala/com/typesafe/tools/mima/core/util/log/Logging.scala index 8d3f9452..3f81e8e0 100644 --- a/core/src/main/scala/com/typesafe/tools/mima/core/util/log/Logging.scala +++ b/core/src/main/scala/com/typesafe/tools/mima/core/util/log/Logging.scala @@ -3,4 +3,5 @@ package com.typesafe.tools.mima.core.util.log trait Logging { def info(str: String): Unit def debugLog(str: String): Unit + def error(str: String): Unit } \ No newline at end of file diff --git a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala index 116291ff..a5f75dd4 100644 --- a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala +++ b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala @@ -18,6 +18,7 @@ class SbtLogger(s: TaskStreams) extends Logging { // Mima is prety chatty def info(str: String): Unit = s.log.debug(str) def debugLog(str: String): Unit = s.log.debug(str) + def error(str: String): Unit = s.log.error(str) } object SbtMima { @@ -74,7 +75,7 @@ object SbtMima { log.info(s"$projectName: found ${backErrors.size+forwErrors.size} potential binary incompatibilities while checking against $module $filteredNote") ((backErrors map {p: core.Problem => prettyPrint(p, "current")}) ++ - (forwErrors map {p: core.Problem => prettyPrint(p, "other")})) foreach { log.info } + (forwErrors map {p: core.Problem => prettyPrint(p, "other")})) foreach { log.error } if (failOnProblem && (backErrors.nonEmpty || forwErrors.nonEmpty)) sys.error(projectName + ": Binary compatibility check failed!") } diff --git a/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala b/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala index 9d775abf..1df41e39 100644 --- a/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala +++ b/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala @@ -53,6 +53,7 @@ object ProblemReportingSpec { final val NoOpLogger = new Logging { override def info(str: String): Unit = () override def debugLog(str: String): Unit = () + override def error(str: String): Unit = () } final val NoMemberInfo = new MemberInfo(NoClass, "", 0, "") From 45b72ce0c5c77f74cde8f2c2428ffca01f155d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Mickevi=C4=8Dius?= Date: Tue, 22 May 2018 11:43:39 +0300 Subject: [PATCH 3/6] Remove never matching cases --- .../main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala index a5f75dd4..a1b0b320 100644 --- a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala +++ b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala @@ -84,11 +84,7 @@ object SbtMima { // version string "x.y.z" is converted to an Int tuple (x, y, z) for comparison val versionOrdering = Ordering[(Int, Int, Int)].on { version: String => val ModuleVersion = """(\d+)\.?(\d+)?\.?(.*)?""".r - val (epoch, major, minor) = version match { - case ModuleVersion(e, m, mi) => (e, m, mi) - case ModuleVersion(e, m, null) => (e, m, "0") - case ModuleVersion(e, null, null) => (e, "0", "0") - } + val ModuleVersion(epoch, major, minor) = version val toNumeric = (revision: String) => Try(revision.replace("x", Short.MaxValue.toString).filter(_.isDigit).toInt).getOrElse(0) (toNumeric(epoch), toNumeric(major), toNumeric(minor)) } From 962e287fc192d925361e39a2ffa4ba58d8749905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Mickevi=C4=8Dius?= Date: Tue, 22 May 2018 11:47:32 +0300 Subject: [PATCH 4/6] Add MiMa excludes --- project/Build.scala | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 0ce616fb..af5ee634 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -134,6 +134,15 @@ object MimaBuild { ), name := buildName + "-core") settings(sonatypePublishSettings:_*) + settings( + mimaBinaryIssueFilters ++= { + import com.typesafe.tools.mima.core._ + Seq( + // Add support for versions with less segments (#212) + ProblemFilters.exclude[ReversedMissingMethodProblem]("com.typesafe.tools.mima.core.util.log.Logging.error") + ) + } + ) ) val myAssemblySettings: Seq[Setting[_]] = (assemblySettings: Seq[Setting[_]]) ++ Seq( @@ -213,7 +222,13 @@ object MimaBuild { ProblemFilters.exclude[MissingClassProblem]("sbt.librarymanagement.UpdateConfiguration$"), ProblemFilters.exclude[MissingClassProblem]("sbt.librarymanagement.DependencyResolution"), ProblemFilters.exclude[MissingClassProblem]("sbt.librarymanagement.ivy.IvyDependencyResolution"), - ProblemFilters.exclude[MissingClassProblem]("sbt.librarymanagement.ivy.IvyDependencyResolution$") + ProblemFilters.exclude[MissingClassProblem]("sbt.librarymanagement.ivy.IvyDependencyResolution$"), + + // Add support for versions with less segments (#212) + // All of these are MiMa sbtplugin internals and can be safely filtered + ProblemFilters.exclude[IncompatibleMethTypeProblem]("com.typesafe.tools.mima.plugin.SbtMima.runMima"), + ProblemFilters.exclude[DirectMissingMethodProblem]("com.typesafe.tools.mima.plugin.SbtMima.reportErrors"), + ProblemFilters.exclude[IncompatibleMethTypeProblem]("com.typesafe.tools.mima.plugin.SbtMima.reportModuleErrors") ) } ) From 7f5f47b71ad7e2a3c1031ab393bd0bb5f7be0bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Mickevi=C4=8Dius?= Date: Tue, 22 May 2018 11:54:10 +0300 Subject: [PATCH 5/6] Log with error level only when fail on error --- .../main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala index a1b0b320..e7d2c610 100644 --- a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala +++ b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala @@ -75,7 +75,10 @@ object SbtMima { log.info(s"$projectName: found ${backErrors.size+forwErrors.size} potential binary incompatibilities while checking against $module $filteredNote") ((backErrors map {p: core.Problem => prettyPrint(p, "current")}) ++ - (forwErrors map {p: core.Problem => prettyPrint(p, "other")})) foreach { log.error } + (forwErrors map {p: core.Problem => prettyPrint(p, "other")})) foreach { p => + if (failOnProblem) log.error(p) + else log.info(p) + } if (failOnProblem && (backErrors.nonEmpty || forwErrors.nonEmpty)) sys.error(projectName + ": Binary compatibility check failed!") } From e39ba9a34d15273107c7157f7283b575a2068841 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 22 May 2018 11:26:40 +0100 Subject: [PATCH 6/6] Send problems to warn logs, instead of info --- .../com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala | 1 + .../scala/com/typesafe/tools/mima/core/util/log/Logging.scala | 3 ++- project/Build.scala | 1 + .../main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala | 3 ++- .../com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala | 1 + 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala b/core/src/main/scala/com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala index 6d6e5087..ede41cbc 100644 --- a/core/src/main/scala/com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala +++ b/core/src/main/scala/com/typesafe/tools/mima/core/util/log/ConsoleLogging.scala @@ -5,5 +5,6 @@ import com.typesafe.tools.mima.core.Config object ConsoleLogging extends Logging { def info(str: String) = if (Config.verbose) println(str) def debugLog(str: String) = if (Config.debug) println(str) + def warn(str: String) = println(str) def error(str: String) = Console.err.println(str) } diff --git a/core/src/main/scala/com/typesafe/tools/mima/core/util/log/Logging.scala b/core/src/main/scala/com/typesafe/tools/mima/core/util/log/Logging.scala index 3f81e8e0..3f2da64b 100644 --- a/core/src/main/scala/com/typesafe/tools/mima/core/util/log/Logging.scala +++ b/core/src/main/scala/com/typesafe/tools/mima/core/util/log/Logging.scala @@ -3,5 +3,6 @@ package com.typesafe.tools.mima.core.util.log trait Logging { def info(str: String): Unit def debugLog(str: String): Unit + def warn(str: String): Unit def error(str: String): Unit -} \ No newline at end of file +} diff --git a/project/Build.scala b/project/Build.scala index af5ee634..7ff199d1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -139,6 +139,7 @@ object MimaBuild { import com.typesafe.tools.mima.core._ Seq( // Add support for versions with less segments (#212) + ProblemFilters.exclude[ReversedMissingMethodProblem]("com.typesafe.tools.mima.core.util.log.Logging.warn") ProblemFilters.exclude[ReversedMissingMethodProblem]("com.typesafe.tools.mima.core.util.log.Logging.error") ) } diff --git a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala index e7d2c610..41ab2da0 100644 --- a/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala +++ b/sbtplugin/src/main/scala/com/typesafe/tools/mima/plugin/SbtMima.scala @@ -18,6 +18,7 @@ class SbtLogger(s: TaskStreams) extends Logging { // Mima is prety chatty def info(str: String): Unit = s.log.debug(str) def debugLog(str: String): Unit = s.log.debug(str) + def warn(str: String): Unit = s.log.warn(str) def error(str: String): Unit = s.log.error(str) } @@ -77,7 +78,7 @@ object SbtMima { ((backErrors map {p: core.Problem => prettyPrint(p, "current")}) ++ (forwErrors map {p: core.Problem => prettyPrint(p, "other")})) foreach { p => if (failOnProblem) log.error(p) - else log.info(p) + else log.warn(p) } if (failOnProblem && (backErrors.nonEmpty || forwErrors.nonEmpty)) sys.error(projectName + ": Binary compatibility check failed!") } diff --git a/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala b/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala index 1df41e39..c3cedde4 100644 --- a/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala +++ b/sbtplugin/src/test/scala/com/typesafe/tools/mima/plugin/ProblemReportingSpec.scala @@ -53,6 +53,7 @@ object ProblemReportingSpec { final val NoOpLogger = new Logging { override def info(str: String): Unit = () override def debugLog(str: String): Unit = () + override def warn(str: String): Unit = () override def error(str: String): Unit = () }