Skip to content

Commit

Permalink
Merge pull request #175 from seigert/fix/155
Browse files Browse the repository at this point in the history
fix #155 by extracting version without suffix
  • Loading branch information
sjrd authored Aug 3, 2023
2 parents b73b134 + a036565 commit 18d39bf
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 25 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# SBT stuff
target/

# Bloop/Metals/VSCode stuff
.bloop
.bsp
.metals
.vscode
metals.sbt
7 changes: 6 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import com.typesafe.tools.mima.core._

inThisBuild(List(
organization := "ch.epfl.scala",
Expand Down Expand Up @@ -37,5 +38,9 @@ lazy val `sbt-version-policy` = project
"io.get-coursier" %% "versions" % "0.3.1",
"com.eed3si9n.verify" %% "verify" % "2.0.1" % Test,
),
testFrameworks += new TestFramework("verify.runner.Framework")
testFrameworks += new TestFramework("verify.runner.Framework"),
mimaBinaryIssueFilters ++= Seq(
// this class is `private` and it's only used from `extractSemVerNumbers` method, which is private
ProblemFilters.exclude[MissingClassProblem]("sbtversionpolicy.DependencyCheckReport$SemVerVersion*")
),
)
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ object DependencyCheckReport {
def message = "missing dependency"
}

private case class SemVerVersion(major: Int, minor: Int, patch: Int, suffix: Seq[Version.Item])

@deprecated("This method is internal.", "1.1.0")
def apply(
currentModules: Map[(String, String), String],
Expand Down Expand Up @@ -153,24 +155,38 @@ object DependencyCheckReport {
previousVersion == currentVersion
case VersionCompatibility.SemVer | VersionCompatibility.EarlySemVer | VersionCompatibility.SemVerSpec =>
// Early SemVer and SemVer Spec are equivalent regarding source compatibility
extractSemVerNumbers(currentVersion).zip(extractSemVerNumbers(previousVersion)).headOption match {
case Some(((currentMajor, currentMinor, currentPatch), (previousMajor, previousMinor, previousPatch))) =>
currentMajor == previousMajor && {
if (currentMajor == 0)
currentMinor == previousMinor && currentPatch == previousPatch
else
currentMinor == previousMinor && currentPatch >= previousPatch
(extractSemVerNumbers(currentVersion), extractSemVerNumbers(previousVersion)) match {
case (Some(currentSemVer), Some(previousSemVer)) =>
def sameMajor = currentSemVer.major == previousSemVer.major
def sameMinor = currentSemVer.minor == previousSemVer.minor
def samePatch = currentSemVer.patch == previousSemVer.patch
def sameSuffix = currentSemVer.suffix == previousSemVer.suffix

if (currentSemVer.major == 0) {
// Before 1.x.y release even patch changes could be source incompatible,
// this includes changes between snapshots and release candidates

sameMajor && sameMinor && samePatch && sameSuffix
} else {
// 1.0.0-RC1 may be source incompatible to 1.0.0-RC2
// but!
// 1.0.1-RC2 must be source compatible both to 1.0.1-RC1 and 1.0.0 (w/o suffix!)
def compatPatch = (samePatch && sameSuffix) || (previousSemVer.suffix.isEmpty || previousSemVer.patch > 0)

sameMajor && sameMinor && compatPatch
}
case None => currentVersion == previousVersion
case _ => false
}
}

private def extractSemVerNumbers(versionString: String): Option[(Int, Int, Int)] = {
private def extractSemVerNumbers(versionString: String): Option[SemVerVersion] = {
val version = Version(versionString)
if (version.items.size == 3 && version.items.forall(_.isInstanceOf[Version.Number])) {
val Seq(major, minor, patch) = version.items.collect { case num: Version.Number => num.value }
Some((major, minor, patch))
} else None // Not a normalized version number (e.g., 1.0.0-RC1)
version.items match {
case Vector(major: Version.Number, minor: Version.Number, patch: Version.Number, suffix @ _*) =>
Some(SemVerVersion(major.value, minor.value, patch.value, suffix))
case _ =>
None // Not a semantic version number (e.g., 1.0-RC1)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,29 @@ object DependencyCheckReportTest extends BasicTestSuite {
withScheme(VersionCompatibility.PackVer) { (isCompatible, isBreaking) =>
isBreaking ("1.0.1", "1.0.0")
isBreaking ("1.1.0", "1.0.0")
isBreaking ("2.0.0", "1.0.0")
isCompatible("1.2.3", "1.2.3")
isBreaking ("1.2.3", "1.2.3-RC1")
isCompatible("1.2.3-RC1", "1.2.3-RC1")
isBreaking ("1.2.3", "1.2.3-RC1")
isCompatible("1.2.3", "1.2.3")
isBreaking ("2.0.0", "1.0.0")
}
withScheme(VersionCompatibility.EarlySemVer) { (isCompatible, isBreaking) =>
isBreaking ("0.1.1", "0.1.0")
isBreaking ("0.2.0", "0.1.0")
isBreaking ("1.0.0", "0.1.0")
isCompatible("1.0.1", "1.0.0")
isBreaking ("1.1.0", "1.0.0")
isBreaking ("2.0.0", "1.0.0")
isBreaking ("1.0.0", "1.0.0-RC1")
isCompatible("1.0.0-RC1", "1.0.0-RC1")
isBreaking ("0.1.1", "0.1.0")
isBreaking ("0.2.0", "0.1.0")
isCompatible("1.0.0-RC1", "1.0.0-RC1")
isBreaking ("1.0.0-RC2", "1.0.0-RC1")
isBreaking ("1.0.0", "1.0.0-RC1")
isCompatible("1.0.1-RC1", "1.0.0")
isCompatible("1.0.1-RC2", "1.0.1-RC1")
isBreaking ("1.0.1", "1.0.0-RC1")
isCompatible("1.0.1", "1.0.0")
isBreaking ("1.1.0-RC1", "1.0.0")
isBreaking ("1.1.0-RC2", "1.1.0-RC1")
isBreaking ("1.1.0", "1.0.0-RC1")
isBreaking ("1.1.0", "1.0.0")
isCompatible("1.2.1-SNAPSHOT", "1.2.0")
isBreaking ("2.0.0-RC1", "1.0.0")
isBreaking ("2.0.0", "1.0.0-RC1")
isBreaking ("2.0.0", "1.0.0")
}
}

Expand Down

0 comments on commit 18d39bf

Please sign in to comment.