Skip to content

Commit

Permalink
Merge pull request #16 from alexarchambault/develop
Browse files Browse the repository at this point in the history
Tweaking
  • Loading branch information
alexarchambault authored Jun 10, 2020
2 parents 01e2f46 + 5b3733a commit 37916ea
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 36 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ The previously compatible version is computed from `version` the following way:

By default, `compatibilityPreviousArtifacts` relies on `mimaPreviousArtifacts` from sbt-mima, so that only setting / changing `mimaPreviousArtifacts` is enough for both sbt-mima and sbt-compatibility.

## `compatibilityReconciliations`
## `compatibilityRules`

`compatibilityReconciliations` allows to specify whether some version bumps are allowed or not, like
`compatibilityRules` allows to specify whether some version bumps are allowed or not, like
```scala
compatibilityReconciliations += "org.scala-lang.modules" %% "scala-xml" % "semver"
compatibilityRules += "org.scala-lang.modules" %% "scala-xml" % "semver"
```

The following compatility types are available:
Expand All @@ -58,7 +58,7 @@ The following compatility types are available:
- `always`: assumes all versions of the matched modules are compatible with each other,
- `strict`: requires exact matches between the wanted and the selected versions of the matched modules.

If no rule for a module is found in `compatibilityReconciliations`, `compatibilityDefaultReconciliation` is used
If no rule for a module is found in `compatibilityRules`, `compatibilityDefaultReconciliation` is used
as a compatibility type. It's default value is `VersionCompatibility.PackVer` (package versioning policy).

## Acknowledgments
Expand Down
24 changes: 24 additions & 0 deletions src/main/scala/sbtcompatibility/SbtCompatibilityInternalKeys.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package sbtcompatibility

import coursier.version.{ModuleMatchers, VersionCompatibility}
import lmcoursier.CoursierConfiguration
import sbt._
import sbt.librarymanagement.{DependencyResolution, ScalaModuleInfo, UpdateConfiguration, UnresolvedWarningConfiguration}

trait SbtCompatibilityInternalKeys {
final val compatibilityCsrConfiguration = taskKey[CoursierConfiguration]("CoursierConfiguration instance to use to fetch previous versions dependencies")
final val compatibilityDependencyResolution = taskKey[DependencyResolution]("DependencyResolution instance to use to fetch previous versions dependencies")
final val compatibilityUpdateConfiguration = taskKey[UpdateConfiguration]("")
final val compatibilityUnresolvedWarningConfiguration = taskKey[UnresolvedWarningConfiguration]("")
final val compatibilityScalaModuleInfo = taskKey[Option[ScalaModuleInfo]]("")

final val compatibilityIgnoreSbtDefaultReconciliations = taskKey[Boolean]("")
final val compatibilityUseCsrConfigReconciliations = taskKey[Boolean]("")

final val compatibilityAutoPreviousArtifacts = taskKey[Seq[ModuleID]]("")
final val compatibilityPreviousArtifactsFromMima = taskKey[Seq[ModuleID]]("")
final val compatibilityPreviousVersions = taskKey[Seq[String]]("")

final val compatibilityDetailedReconciliations = taskKey[Seq[(ModuleMatchers, VersionCompatibility)]]("")
final val compatibilityFallbackReconciliations = taskKey[Seq[(ModuleMatchers, VersionCompatibility)]]("")
}
27 changes: 9 additions & 18 deletions src/main/scala/sbtcompatibility/SbtCompatibilityKeys.scala
Original file line number Diff line number Diff line change
@@ -1,34 +1,25 @@
package sbtcompatibility

import coursier.version.{ModuleMatchers, VersionCompatibility}
import lmcoursier.CoursierConfiguration
import coursier.version.VersionCompatibility
import sbt._
import sbt.librarymanagement.{DependencyResolution, ScalaModuleInfo, UpdateConfiguration, UnresolvedWarningConfiguration}
import sbt.librarymanagement.DependencyBuilders.OrganizationArtifactName

trait SbtCompatibilityKeys {
final val compatibilityPreviousArtifacts = taskKey[Seq[ModuleID]]("")
final val compatibilityReportDependencyIssues = taskKey[Unit]("")
final val compatibilityCheck = taskKey[Unit]("Runs both compatibilityReportDependencyIssues and mimaReportBinaryIssues")

final val compatibilityReconciliations = taskKey[Seq[ModuleID]]("")
final val compatibilityRules = taskKey[Seq[ModuleID]]("")
@deprecated("Use compatibilityRules instead", "0.0.8")
final def compatibilityReconciliations = compatibilityRules
final val compatibilityIgnored = taskKey[Seq[OrganizationArtifactName]]("")
final val compatibilityDetailedReconciliations = taskKey[Seq[(ModuleMatchers, VersionCompatibility)]]("")
final val compatibilityCheckDirection = taskKey[Direction]("")

final val compatibilityFindDependencyIssues = taskKey[Seq[(ModuleID, DependencyCheckReport)]]("")

final val compatibilityCsrConfiguration = taskKey[CoursierConfiguration]("CoursierConfiguration instance to use to fetch previous versions dependencies")
final val compatibilityDependencyResolution = taskKey[DependencyResolution]("DependencyResolution instance to use to fetch previous versions dependencies")
final val compatibilityUpdateConfiguration = taskKey[UpdateConfiguration]("")
final val compatibilityUnresolvedWarningConfiguration = taskKey[UnresolvedWarningConfiguration]("")
final val compatibilityScalaModuleInfo = taskKey[Option[ScalaModuleInfo]]("")
final val compatibilityDefaultRules = taskKey[Seq[ModuleID]]("")
final val compatibilityDefaultReconciliation = taskKey[Option[VersionCompatibility]]("")

final val compatibilityIgnoreSbtDefaultReconciliations = taskKey[Boolean]("")
final val compatibilityUseCsrConfigReconciliations = taskKey[Boolean]("")
final val compatibilityDefaultReconciliation = taskKey[VersionCompatibility]("")

final val compatibilityAutoPreviousArtifacts = taskKey[Seq[ModuleID]]("")
final val compatibilityPreviousArtifactsFromMima = taskKey[Seq[ModuleID]]("")
final val compatibilityPreviousVersions = taskKey[Seq[String]]("")
}
final val compatibilityInternal: SbtCompatibilityInternalKeys =
new SbtCompatibilityInternalKeys {}
}
46 changes: 39 additions & 7 deletions src/main/scala/sbtcompatibility/SbtCompatibilitySettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package sbtcompatibility

import com.typesafe.tools.mima.plugin.MimaPlugin
import coursier.version.{ModuleMatcher, ModuleMatchers, VersionCompatibility}
import sbt.{Compile, Def}
import sbt._
import sbt.Keys._
import sbt.librarymanagement.CrossVersion
import lmcoursier.CoursierDependencyResolution
Expand All @@ -15,6 +15,7 @@ object SbtCompatibilitySettings {

private val keys: SbtCompatibilityKeys = new SbtCompatibilityKeys {}
import keys._
import keys.compatibilityInternal._

def updateSettings = Def.settings(
compatibilityCsrConfiguration := csrConfiguration.value
Expand All @@ -33,20 +34,51 @@ object SbtCompatibilitySettings {
compatibilityScalaModuleInfo := scalaModuleInfo.value
)

// Trying to mimick the current default behavior of evicted in sbt, that is
// - assume scala libraries follow PVP,
// - assume Java libraries follow semver.
private def defaultRules = Seq(
("*" % "*" % "pvp").cross(CrossVersion.full),
"*" %% "*" % "pvp",
"*" % "*" % "semver"
)

def reconciliationBuildSettings = Def.settings(
compatibilityCheckDirection := Direction.backward,
compatibilityIgnoreSbtDefaultReconciliations := true,
compatibilityUseCsrConfigReconciliations := true,
compatibilityReconciliations := Seq.empty,
compatibilityRules := Seq.empty,
compatibilityDefaultRules := defaultRules,
compatibilityIgnored := Seq.empty,
compatibilityDefaultReconciliation := VersionCompatibility.PackVer
compatibilityDefaultReconciliation := None
)

def reconciliationSettings = Def.settings(
compatibilityFallbackReconciliations := {
val sv = scalaVersion.value
val sbv = scalaBinaryVersion.value
val defaultReconciliationOpt = compatibilityDefaultReconciliation.value
val (fallbackRules, fallbackMatchers) = {
val rules: Seq[ModuleID] = compatibilityDefaultRules.value
defaultReconciliationOpt match {
case None => (rules, Nil)
case Some(default) => (Nil, Seq(ModuleMatchers.all -> default))
}
}
fallbackRules.map { mod =>
val rec = VersionCompatibility(mod.revision) match {
case Some(r) => r
case None => sys.error(s"Unrecognized reconciliation '${mod.revision}' in $mod")
}
val name = CrossVersion(mod.crossVersion, sv, sbv).fold(mod.name)(_(mod.name))
val matchers = ModuleMatchers.only(mod.organization, name)
(matchers, rec)
} ++ fallbackMatchers
},
compatibilityDetailedReconciliations := {
val sv = scalaVersion.value
val sbv = scalaBinaryVersion.value
compatibilityReconciliations.value.map { mod =>
compatibilityRules.value.map { mod =>
val rec = VersionCompatibility(mod.revision) match {
case Some(r) => r
case None => sys.error(s"Unrecognized reconciliation '${mod.revision}' in $mod")
Expand Down Expand Up @@ -132,10 +164,10 @@ object SbtCompatibilitySettings {
}

val ours = compatibilityDetailedReconciliations.value
val fallback = compatibilityFallbackReconciliations.value

ours ++ fromCsrConfig0
ours ++ fromCsrConfig0 ++ fallback
}
val defaultReconciliation = compatibilityDefaultReconciliation.value

val currentModules = DependencyCheck.modulesOf(compileReport, sv, sbv, log)

Expand All @@ -147,7 +179,7 @@ object SbtCompatibilitySettings {
currentModules,
previousModuleId,
reconciliations,
defaultReconciliation,
VersionCompatibility.Strict,
sv,
sbv,
depRes,
Expand Down
59 changes: 59 additions & 0 deletions src/sbt-test/sbt-compatibility/defaults/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
lazy val v1 = project
.settings(
check := {},
name := "defaults-test",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-xml" % "1.0.6",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.10.4"
),
version := "0.1.0"
)

lazy val bumpScala = project
.settings(
name := "defaults-test",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-xml" % "1.2.0",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.10.4"
),
version := "0.1.1",
checkFails
)

lazy val bumpJava = project
.settings(
name := "defaults-test",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-xml" % "1.0.6",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.11.0"
),
version := "0.1.1"
)

lazy val bumpScalaAndAddRule = project
.settings(
name := "defaults-test",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-xml" % "1.2.0",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.10.4"
),
version := "0.1.1",
compatibilityRules += "org.scala-lang.modules" %% "*" % "semver"
)

inThisBuild(List(
scalaVersion := "2.12.11",
organization := "io.github.alexarchambault.sbtcompatibility.test",
))

lazy val check = taskKey[Unit]("")

lazy val checkFails = Def.settings(
check := {
val direction = compatibilityCheckDirection.value
val reports = compatibilityFindDependencyIssues.value
val failed = reports.exists(!_._2.validated(direction))
assert(failed, s"Expected a failed report in $reports")
}
)

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("io.github.alexarchambault.sbt" % "sbt-compatibility" % sys.props("plugin.version"))
5 changes: 5 additions & 0 deletions src/sbt-test/sbt-compatibility/defaults/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
> v1/publishLocal
-> bumpScala/compatibilityReportDependencyIssues
> bumpScala/check
> bumpJava/compatibilityReportDependencyIssues
> bumpScalaAndAddRule/compatibilityReportDependencyIssues
2 changes: 1 addition & 1 deletion src/sbt-test/sbt-compatibility/in-this-build/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ lazy val b = project
inThisBuild(List(
scalaVersion := "2.12.11",
organization := "io.github.alexarchambault.sbtcompatibility.test2",
compatibilityReconciliations += "org.scala-lang.modules" %% "scala-xml" % "semver"
compatibilityRules += "org.scala-lang.modules" %% "scala-xml" % "semver"
))

3 changes: 1 addition & 2 deletions src/sbt-test/sbt-compatibility/run-mima/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ lazy val core = project
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.3.3",
"io.argonaut" %% "argonaut" % "6.1a"
),
compatibilityPreviousArtifacts := compatibilityAutoPreviousArtifacts.value
)
)
7 changes: 3 additions & 4 deletions src/sbt-test/sbt-compatibility/simple/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ lazy val d = project
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.3.3"
),
compatibilityDefaultReconciliation := VersionCompatibility.Strict,
compatibilityDefaultReconciliation := Some(VersionCompatibility.Strict),
checkFails,
checkMimaPreviousArtifactsSet,
version := "0.1.1"
Expand All @@ -85,7 +85,7 @@ lazy val f = project
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.3.3"
),
compatibilityReconciliations += "com.chuusai" %% "shapeless" % "strict",
compatibilityRules += "com.chuusai" %% "shapeless" % "strict",
version := "0.1.1"
)

Expand All @@ -96,7 +96,7 @@ lazy val g = project
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.3.3"
),
compatibilityReconciliations += "com.chuusai" %% "shapeless" % "pvp",
compatibilityRules += "com.chuusai" %% "shapeless" % "pvp",
version := "0.1.1"
)

Expand All @@ -108,7 +108,6 @@ inThisBuild(List(
lazy val check = taskKey[Unit]("")

lazy val shared = Def.settings(
compatibilityPreviousArtifacts := compatibilityAutoPreviousArtifacts.value,
check := {}
)

Expand Down

0 comments on commit 37916ea

Please sign in to comment.