From 4a1ab6f71e58af21b5fe66dd811ab105d660adea Mon Sep 17 00:00:00 2001 From: Naftoli Gugenheim Date: Thu, 6 Jan 2022 21:29:57 -0500 Subject: [PATCH 1/5] Make previousVersionsFromRepo public --- .../src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala index 234ca4c..e8969b1 100644 --- a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala +++ b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala @@ -27,7 +27,7 @@ object SbtVersionPolicyMima extends AutoPlugin { private def moduleName(m: ModuleID, sv: String, sbv: String): String = moduleName(m.crossVersion, sv, sbv, m.name) - private lazy val previousVersionsFromRepo = Def.setting { + lazy val previousVersionsFromRepo = Def.setting { val projId = Keys.projectID.value val sv = Keys.scalaVersion.value From 7dc19ac5196f53f9a0e70c39bf912ac2864570b4 Mon Sep 17 00:00:00 2001 From: Naftoli Gugenheim Date: Thu, 6 Jan 2022 21:35:55 -0500 Subject: [PATCH 2/5] versionPolicyDependencyIssuesReporter task It provides a DependencyCheck.Reporter, which enables passing an arbitrary compatibility intention and previous module IDs, while still computing everything else from SBT. Then, versionPolicyFindDependencyIssues is refactored to use versionPolicyDependencyIssuesReporter, and only supply the compatibility intention and previous module IDs to it, based on SBT settings as before. --- .../SbtVersionPolicyKeys.scala | 2 + .../SbtVersionPolicySettings.scala | 63 +++++++++---------- .../internal/DependencyCheck.scala | 41 ++++++++++++ 3 files changed, 71 insertions(+), 35 deletions(-) diff --git a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyKeys.scala b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyKeys.scala index d1e4142..416be0d 100644 --- a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyKeys.scala +++ b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyKeys.scala @@ -3,6 +3,7 @@ package sbtversionpolicy import coursier.version.VersionCompatibility import sbt._ import sbt.librarymanagement.DependencyBuilders.OrganizationArtifactName +import sbtversionpolicy.internal.DependencyCheck import scala.util.matching.Regex @@ -13,6 +14,7 @@ trait SbtVersionPolicyKeys { final val versionPolicyCheck = taskKey[Unit]("Runs both versionPolicyReportDependencyIssues and versionPolicyMimaCheck") final val versionPolicyMimaCheck = taskKey[Unit]("Runs Mima to check backward or forward compatibility depending on the intended change defined via versionPolicyIntention.") final val versionPolicyForwardCompatibilityCheck = taskKey[Unit]("Report forward binary compatible issues from Mima.") + final val versionPolicyDependencyIssuesReporter = taskKey[DependencyCheck.Reporter]("Helper to find issues in the library dependencies.") final val versionPolicyFindDependencyIssues = taskKey[Seq[(ModuleID, DependencyCheckReport)]]("Compatibility issues in the library dependencies.") final val versionCheck = taskKey[Unit]("Checks that the version is consistent with the intended compatibility level defined via versionPolicyIntention") diff --git a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicySettings.scala b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicySettings.scala index de059d5..003f0e1 100644 --- a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicySettings.scala +++ b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicySettings.scala @@ -108,7 +108,7 @@ object SbtVersionPolicySettings { ) def findIssuesSettings = Def.settings( - versionPolicyFindDependencyIssues := { + versionPolicyDependencyIssuesReporter := { val log = streams.value.log val sv = scalaVersion.value val sbv = scalaBinaryVersion.value @@ -117,9 +117,6 @@ object SbtVersionPolicySettings { sys.error("Compile configuration not found in update report") } - val compatibilityIntention = - versionPolicyIntention.?.value - .getOrElse(throw new MessageOnlyException("Please set the key versionPolicyIntention to declare the compatibility you want to check")) val depRes = versionPolicyDependencyResolution.value val scalaModuleInf = versionPolicyScalaModuleInfo.value val updateConfig = versionPolicyUpdateConfiguration.value @@ -140,32 +137,24 @@ object SbtVersionPolicySettings { log ) + new DependencyCheck.Reporter( + excludedModules, + currentDependencies, + reconciliations, + VersionCompatibility.Strict, + sv, + sbv, + depRes, + scalaModuleInf, + updateConfig, + warningConfig, + log + ) + }, + versionPolicyFindDependencyIssues := { + val compatibilityIntention = requirePolicyIntentionOrThrow(versionPolicyIntention.?.value) val previousModuleIds = versionPolicyPreviousArtifacts.value - - // Skip dependency check if no compatibility is intended - if (compatibilityIntention == Compatibility.None) Nil else { - - previousModuleIds.map { previousModuleId => - - val report0 = DependencyCheck.report( - compatibilityIntention, - excludedModules, - currentDependencies, - previousModuleId, - reconciliations, - VersionCompatibility.Strict, - sv, - sbv, - depRes, - scalaModuleInf, - updateConfig, - warningConfig, - log - ) - - (previousModuleId, report0) - } - } + versionPolicyDependencyIssuesReporter.value.apply(compatibilityIntention, previousModuleIds) }, versionPolicyReportDependencyIssues := { val log = streams.value.log @@ -173,9 +162,7 @@ object SbtVersionPolicySettings { val sbv = scalaBinaryVersion.value val direction = versionPolicyCheckDirection.value val reports = versionPolicyFindDependencyIssues.value - val intention = - versionPolicyIntention.?.value - .getOrElse(throw new MessageOnlyException("Please set the key versionPolicyIntention to declare the compatibility you want to check")) + val intention = requirePolicyIntentionOrThrow(versionPolicyIntention.?.value) val currentModule = projectID.value val formattedPreviousVersions = formatVersions(versionPolicyPreviousVersions.value) @@ -263,9 +250,7 @@ object SbtVersionPolicySettings { }, versionPolicyMimaCheck := Def.taskDyn { import Compatibility._ - val compatibility = - versionPolicyIntention.?.value - .getOrElse(throw new MessageOnlyException("Please set the key versionPolicyIntention to declare the compatibility you want to check")) + val compatibility = requirePolicyIntentionOrThrow(versionPolicyIntention.?.value) val log = streams.value.log val currentModule = projectID.value val formattedPreviousVersions = formatVersions(versionPolicyPreviousVersions.value) @@ -302,6 +287,14 @@ object SbtVersionPolicySettings { }.value ) + private def requirePolicyIntentionOrThrow(maybeCompatibility: Option[Compatibility]) = + maybeCompatibility + .getOrElse( + throw new MessageOnlyException( + "Please set the key versionPolicyIntention to declare the compatibility you want to check" + ) + ) + def skipSettings = Seq( versionCheck / skip := (publish / skip).value, versionPolicyCheck / skip := (publish / skip).value diff --git a/sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala b/sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala index c895c64..101248d 100644 --- a/sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala +++ b/sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala @@ -75,6 +75,47 @@ object DependencyCheck { log ) + class Reporter( + excludedModules: Set[(String, String)], + currentDependencies: Map[(String, String), String], + reconciliations: Seq[(ModuleMatchers, VersionCompatibility)], + defaultReconciliation: VersionCompatibility, + sv: String, + sbv: String, + depRes: DependencyResolution, + scalaModuleInf: Option[ScalaModuleInfo], + updateConfig: UpdateConfiguration, + warningConfig: UnresolvedWarningConfiguration, + log: Logger + ) { + def apply(compatibilityIntention: Compatibility, previousModuleIds: Seq[ModuleID]) = + // Skip dependency check if no compatibility is intended + if (compatibilityIntention == Compatibility.None) Nil else { + + previousModuleIds.map { previousModuleId => + + val report0 = report( + compatibilityIntention, + excludedModules, + currentDependencies, + previousModuleId, + reconciliations, + defaultReconciliation, + sv, + sbv, + depRes, + scalaModuleInf, + updateConfig, + warningConfig, + log + ) + + (previousModuleId, report0) + } + } + + } + private[sbtversionpolicy] def report( compatibilityIntention: Compatibility, excludedModules: Set[(String, String)], From bd7b3e8b8fba4c5be696a10eac4d6991761a62b7 Mon Sep 17 00:00:00 2001 From: Naftoli Gugenheim Date: Thu, 6 Jan 2022 21:37:19 -0500 Subject: [PATCH 3/5] Split out version strings -> artifacts logic into public methods --- .../SbtVersionPolicyMima.scala | 24 ++++++++++--------- .../SbtVersionPolicySettings.scala | 23 ++++++++++-------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala index e8969b1..46094b3 100644 --- a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala +++ b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicyMima.scala @@ -103,18 +103,20 @@ object SbtVersionPolicyMima extends AutoPlugin { }, mimaPreviousArtifacts := { - val projId = Keys.projectID.value.withExplicitArtifacts(Vector.empty) - val previousVersions0 = versionPolicyPreviousVersions.value - - previousVersions0.toSet.map { version => - projId - .withExtraAttributes { - projId.extraAttributes - .filter(!_._1.stripPrefix("e:").startsWith("info.")) - } - .withRevision(version) - } + computePreviousArtifacts(Keys.projectID.value, versionPolicyPreviousVersions.value) } ) + def computePreviousArtifacts(projectID: ModuleID, previousVersions: Seq[String]) = { + val projId = projectID.withExplicitArtifacts(Vector.empty) + + previousVersions.toSet.map { version => + projId + .withExtraAttributes { + projId.extraAttributes + .filter(!_._1.stripPrefix("e:").startsWith("info.")) + } + .withRevision(version) + } + } } diff --git a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicySettings.scala b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicySettings.scala index 003f0e1..0e5497a 100644 --- a/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicySettings.scala +++ b/sbt-version-policy/src/main/scala/sbtversionpolicy/SbtVersionPolicySettings.scala @@ -93,20 +93,23 @@ object SbtVersionPolicySettings { def previousArtifactsSettings = Def.settings( versionPolicyPreviousArtifactsFromMima := { - import Ordering.Implicits._ - MimaPlugin.autoImport.mimaPreviousArtifacts.value - .toVector - .map { mod => - val splitVersion = mod.revision.split('.').map(s => Try(s.toInt).getOrElse(-1)).toSeq - (splitVersion, mod) - } - .sortBy(_._1) - .map(_._2) + fromMimaArtifacts(MimaPlugin.autoImport.mimaPreviousArtifacts.value) }, - versionPolicyPreviousArtifacts := versionPolicyPreviousArtifactsFromMima.value ) + def fromMimaArtifacts(artifacts: Set[sbt.ModuleID]) = { + import Ordering.Implicits.* + artifacts + .toVector + .map { mod => + val splitVersion = mod.revision.split('.').map(s => Try(s.toInt).getOrElse(-1)).toSeq + (splitVersion, mod) + } + .sortBy(_._1) + .map(_._2) + } + def findIssuesSettings = Def.settings( versionPolicyDependencyIssuesReporter := { val log = streams.value.log From 0ead71afe90e2ed983c5f014c2ba3a0857d4d558 Mon Sep 17 00:00:00 2001 From: Naftoli Gugenheim Date: Sat, 8 Jan 2022 19:12:22 -0500 Subject: [PATCH 4/5] Set versionPolicyIntention := Compatibility.BinaryCompatible --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 98c3ac4..1e9c950 100644 --- a/build.sbt +++ b/build.sbt @@ -11,7 +11,7 @@ inThisBuild(List( url("https://github.com/alexarchambault") ) ), - versionPolicyIntention := Compatibility.BinaryAndSourceCompatible, + versionPolicyIntention := Compatibility.BinaryCompatible, libraryDependencySchemes += "com.typesafe" %% "mima-core" % "semver-spec" )) From a89f41f86c7af72552264f9d2c15f1d250f5c9ae Mon Sep 17 00:00:00 2001 From: nafg <98384+nafg@users.noreply.github.com> Date: Thu, 14 Apr 2022 16:55:51 -0400 Subject: [PATCH 5/5] Update sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala Co-authored-by: Julien Richard-Foy --- .../main/scala/sbtversionpolicy/internal/DependencyCheck.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala b/sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala index 101248d..05640f5 100644 --- a/sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala +++ b/sbt-version-policy/src/main/scala/sbtversionpolicy/internal/DependencyCheck.scala @@ -81,7 +81,7 @@ object DependencyCheck { reconciliations: Seq[(ModuleMatchers, VersionCompatibility)], defaultReconciliation: VersionCompatibility, sv: String, - sbv: String, + scalaBinaryVersion: String, depRes: DependencyResolution, scalaModuleInf: Option[ScalaModuleInfo], updateConfig: UpdateConfiguration,