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 65c6173f..2e95ebd2 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 @@ -1,20 +1,16 @@ package com.typesafe.tools.mima package plugin -import com.typesafe.tools.mima.core.Problem -import sbt.* -import sbt.Keys.* - +import sbt.*, Keys.* +import core.* /** MiMa's sbt plugin. */ object MimaPlugin extends AutoPlugin { override def trigger = allRequirements object autoImport extends MimaKeys - import autoImport.* - override def globalSettings: Seq[Def.Setting[_]] = Seq( mimaPreviousArtifacts := NoPreviousArtifacts, mimaExcludeAnnotations := Nil, @@ -25,30 +21,6 @@ object MimaPlugin extends AutoPlugin { mimaCheckDirection := "backward", ) - trait ArtifactsToClassfiles { - def apply(artifacts: Set[ModuleID]): Map[ModuleID, File] - } - - val artifactsToClassfiles = Def.task { - val depRes = mimaDependencyResolution.value - val taskStreams = streams.value - val smi = scalaModuleInfo.value - new ArtifactsToClassfiles { - override def apply(artifacts: Set[sbt.ModuleID]) = - artifacts match { - case _: NoPreviousArtifacts.type => NoPreviousClassfiles - case previousArtifacts => - previousArtifacts.iterator.map { m => - val moduleId = CrossVersion(m, smi) match { - case Some(f) => m.withName(f(m.name)).withCrossVersion(CrossVersion.disabled) - case None => m - } - moduleId -> SbtMima.getPreviousArtifact(moduleId, depRes, taskStreams) - }.toMap - } - } - } - override def projectSettings: Seq[Def.Setting[_]] = Seq( mimaReportBinaryIssues := { binaryIssuesIterator.value.foreach { case (moduleId, problems) => @@ -67,7 +39,7 @@ object MimaPlugin extends AutoPlugin { }, mimaDependencyResolution := dependencyResolution.value, mimaPreviousClassfiles := { - artifactsToClassfiles.value.apply(mimaPreviousArtifacts.value) + artifactsToClassfiles.value.toClassfiles(mimaPreviousArtifacts.value) }, mimaCurrentClassfiles := (Compile / classDirectory).value, mimaFindBinaryIssues := binaryIssuesIterator.value.toMap, @@ -80,50 +52,64 @@ object MimaPlugin extends AutoPlugin { @deprecated("Switch to enablePlugins(MimaPlugin)", "0.7.0") def mimaDefaultSettings: Seq[Setting[_]] = globalSettings ++ buildSettings ++ projectSettings - private def binaryIssueFilters = Def.task { - val noSigs = core.ProblemFilters.exclude[core.IncompatibleSignatureProblem]("*") - mimaBinaryIssueFilters.value ++ (if (mimaReportSignatureProblems.value) Nil else Seq(noSigs)) + trait ArtifactsToClassfiles { + def toClassfiles(previousArtifacts: Set[ModuleID]): Map[ModuleID, File] } trait BinaryIssuesFinder { - def iterator(prevClassFiles: Map[ModuleID, File], - direction: String): Iterator[(ModuleID, (List[Problem], List[Problem]))] + def runMima(prevClassFiles: Map[ModuleID, File], checkDirection: String) + : Iterator[(ModuleID, (List[Problem], List[Problem]))] } - // Allows reuse between mimaFindBinaryIssues and mimaReportBinaryIssues - // without blowing up the Akka build's heap - def binaryIssuesFinder = Def.task { + val artifactsToClassfiles: Def.Initialize[Task[ArtifactsToClassfiles]] = Def.task { + val depRes = mimaDependencyResolution.value + val taskStreams = streams.value + val smi = scalaModuleInfo.value + previousArtifacts => previousArtifacts match { + case _: NoPreviousArtifacts.type => NoPreviousClassfiles + case previousArtifacts => + previousArtifacts.iterator.map { m => + val moduleId = CrossVersion(m, smi) match { + case Some(f) => m.withName(f(m.name)).withCrossVersion(CrossVersion.disabled) + case None => m + } + moduleId -> SbtMima.getPreviousArtifact(moduleId, depRes, taskStreams) + }.toMap + } + } + + val binaryIssuesFinder: Def.Initialize[Task[BinaryIssuesFinder]] = Def.task { val log = streams.value.log val currClassfiles = mimaCurrentClassfiles.value val cp = (mimaFindBinaryIssues / fullClasspath).value val sv = scalaVersion.value val excludeAnnots = mimaExcludeAnnotations.value.toList - val requirePrevious = mimaFailOnNoPrevious.value + val failOnNoPrevious = mimaFailOnNoPrevious.value val projName = name.value - new BinaryIssuesFinder { - override def iterator(prevClassfiles: Map[sbt.ModuleID, sbt.File], direction: String) = { - if (prevClassfiles eq NoPreviousClassfiles) { - val msg = "mimaPreviousArtifacts not set, not analyzing binary compatibility" - if (requirePrevious) - sys.error(msg) - else - log.info(s"$projName: $msg") - } else if (prevClassfiles.isEmpty) - log.info(s"$projName: mimaPreviousArtifacts is empty, not analyzing binary compatibility.") - - prevClassfiles.iterator.map { case (moduleId, prevClassfiles) => - moduleId -> SbtMima.runMima(prevClassfiles, currClassfiles, cp, direction, sv, log, excludeAnnots) - } + (prevClassfiles, checkDirection) => { + if (prevClassfiles eq NoPreviousClassfiles) { + val msg = "mimaPreviousArtifacts not set, not analyzing binary compatibility" + if (failOnNoPrevious) sys.error(msg) else log.info(s"$projName: $msg") + } else if (prevClassfiles.isEmpty) { + log.info(s"$projName: mimaPreviousArtifacts is empty, not analyzing binary compatibility.") + } + + prevClassfiles.iterator.map { case (moduleId, prevClassfiles) => + moduleId -> SbtMima.runMima(prevClassfiles, currClassfiles, cp, checkDirection, sv, log, excludeAnnots) } } } + private val binaryIssueFilters = Def.task { + val noSigs = ProblemFilters.exclude[IncompatibleSignatureProblem]("*") + mimaBinaryIssueFilters.value ++ (if (mimaReportSignatureProblems.value) Nil else Seq(noSigs)) + } + // Allows reuse between mimaFindBinaryIssues and mimaReportBinaryIssues // without blowing up the Akka build's heap - private def binaryIssuesIterator = Def.task { - val it = binaryIssuesFinder.value - it.iterator(mimaPreviousClassfiles.value, mimaCheckDirection.value) + private val binaryIssuesIterator = Def.task { + binaryIssuesFinder.value.runMima(mimaPreviousClassfiles.value, mimaCheckDirection.value) } // Used to differentiate unset mimaPreviousArtifacts from empty mimaPreviousArtifacts