Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow checking in an on-the-fly mode while still benefiting from other sbt settings #680

Merged
merged 2 commits into from
Apr 7, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package com.typesafe.tools.mima
package plugin

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._
import autoImport.*

override def globalSettings: Seq[Def.Setting[_]] = Seq(
mimaPreviousArtifacts := NoPreviousArtifacts,
Expand Down Expand Up @@ -38,19 +39,7 @@ object MimaPlugin extends AutoPlugin {
},
mimaDependencyResolution := dependencyResolution.value,
mimaPreviousClassfiles := {
val depRes = mimaDependencyResolution.value
val taskStreams = streams.value
mimaPreviousArtifacts.value match {
case _: NoPreviousArtifacts.type => NoPreviousClassfiles
case previousArtifacts =>
previousArtifacts.iterator.map { m =>
val moduleId = CrossVersion(m, scalaModuleInfo.value) match {
case Some(f) => m.withName(f(m.name)).withCrossVersion(CrossVersion.disabled)
case None => m
}
moduleId -> SbtMima.getPreviousArtifact(moduleId, depRes, taskStreams)
}.toMap
}
artifactsToClassfiles.value.toClassfiles(mimaPreviousArtifacts.value)
},
mimaCurrentClassfiles := (Compile / classDirectory).value,
mimaFindBinaryIssues := binaryIssuesIterator.value.toMap,
Expand All @@ -63,31 +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]
}

// Allows reuse between mimaFindBinaryIssues and mimaReportBinaryIssues
// without blowing up the Akka build's heap
private def binaryIssuesIterator = Def.task {
trait BinaryIssuesFinder {
def runMima(prevClassFiles: Map[ModuleID, File], checkDirection: String)
: Iterator[(ModuleID, (List[Problem], List[Problem]))]
}

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 prevClassfiles = mimaPreviousClassfiles.value
val currClassfiles = mimaCurrentClassfiles.value
val cp = (mimaFindBinaryIssues / fullClasspath).value
val sv = scalaVersion.value
val excludeAnnots = mimaExcludeAnnotations.value.toList
val failOnNoPrevious = mimaFailOnNoPrevious.value
val projName = name.value

(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.")
}

if (prevClassfiles eq NoPreviousClassfiles) {
val msg = "mimaPreviousArtifacts not set, not analyzing binary compatibility"
if (mimaFailOnNoPrevious.value) sys.error(msg) else log.info(s"${name.value}: $msg")
} else if (prevClassfiles.isEmpty) {
log.info(s"${name.value}: mimaPreviousArtifacts is empty, not analyzing binary compatibility.")
prevClassfiles.iterator.map { case (moduleId, prevClassfiles) =>
moduleId -> SbtMima.runMima(prevClassfiles, currClassfiles, cp, checkDirection, sv, log, excludeAnnots)
}
}
}

prevClassfiles.iterator.map { case (moduleId, prevClassfiles) =>
moduleId -> SbtMima.runMima(prevClassfiles, currClassfiles, cp, mimaCheckDirection.value, 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 val binaryIssuesIterator = Def.task {
binaryIssuesFinder.value.runMima(mimaPreviousClassfiles.value, mimaCheckDirection.value)
}

// Used to differentiate unset mimaPreviousArtifacts from empty mimaPreviousArtifacts
Expand Down