Skip to content

Commit

Permalink
Fix latest-by-scala-version badge summary to prefer releases
Browse files Browse the repository at this point in the history
Currently, for the `content-api-firehose-client`, the Scaladex badges page
is showing some contrasting values:

https://index.scala-lang.org/guardian/content-api-firehose-client/badges

* The 'Latest version' badge is showing a good version:
  1.0.12
* The 'JVM badge' (which shows a summary of latest versions by supported
  Scala version, introduced with #660)
  is showing an undesireable pre-release version:
  1.0.13-PREVIEW.rt-dbremove-travis-file.2024-01-10T1738.6e259255

You can see both values on the versions page, but only if you tick the
'Show pre-release versions' button:

* https://index.scala-lang.org/guardian/content-api-firehose-client/artifacts/content-api-firehose-client
* https://index.scala-lang.org/guardian/content-api-firehose-client/artifacts/content-api-firehose-client?pre-releases=true#
  • Loading branch information
rtyley committed Jan 13, 2024
1 parent 6ddd036 commit 8b27462
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ object SemanticVersion {
)
}

/**
* Often we will prefer the latest release, but if there is no full release, we will select the most recent
* pre-release.
*/
val PreferReleases: Ordering[SemanticVersion] =
Ordering.by[SemanticVersion, Boolean](_.isRelease).orElse(ordering)

private def MajorP[A: P]: P[Int] = Number

// http://semver.org/#spec-item-10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package scaladex.core.model
import org.scalatest.funspec.AsyncFunSpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.prop.TableDrivenPropertyChecks
import scaladex.core.model.SemanticVersion.PreferReleases
import scaladex.core.test.Values._

class SemanticVersionTests extends AsyncFunSpec with Matchers with TableDrivenPropertyChecks {
it("should parse any version") {
Expand Down Expand Up @@ -39,6 +41,12 @@ class SemanticVersionTests extends AsyncFunSpec with Matchers with TableDrivenPr
forAll(inputs)((lower, higher) => lower shouldBe <(higher))
}

it("should allow us to prefer releases over pre-releases") {
val versions = Seq(`7.0.0`, `7.1.0`, `7.2.0-PREVIEW.1`)
versions.max shouldBe `7.2.0-PREVIEW.1`
versions.max(PreferReleases) shouldBe `7.1.0`
}

it("should encode and decode any version") {
val inputs = Table[SemanticVersion](
"semanticVersion",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ object Values {
val `2.7.0` = PatchVersion(2, 7, 0)
val `7.0.0` = PatchVersion(7, 0, 0)
val `7.1.0` = PatchVersion(7, 1, 0)
val `7.2.0-PREVIEW.1` = SemanticVersion.parse("7.2.0-PREVIEW.1").get
val `7.2.0-PREVIEW.2` = SemanticVersion.parse("7.2.0-PREVIEW.2").get
val `7.2.0` = PatchVersion(7, 2, 0)
val `7.3.0` = PatchVersion(7, 3, 0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import scaladex.core.model.Scala
import scaladex.core.model.ScalaJs
import scaladex.core.model.ScalaNative
import scaladex.core.model.SemanticVersion
import scaladex.core.model.SemanticVersion.PreferReleases
import scaladex.core.service.WebDatabase

class Badges(database: WebDatabase)(implicit executionContext: ExecutionContext) {
Expand Down Expand Up @@ -173,7 +174,7 @@ object Badges {

private[route] def summaryOfLatestVersions(versionsByScalaVersions: Map[Scala, Seq[SemanticVersion]]): String =
versionsByScalaVersions.view
.mapValues(_.max)
.mapValues(_.max(PreferReleases))
.groupMap { case (_, latestVersion) => latestVersion } { case (scalaVersion, _) => scalaVersion }
.toSeq
.sortBy(_._1)(SemanticVersion.ordering.reverse)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import akka.http.scaladsl.model.Uri
import akka.http.scaladsl.model.headers.Location
import akka.http.scaladsl.server.Route
import org.scalatest.BeforeAndAfterAll
import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers
import scaladex.core.model.Scala._
import scaladex.core.test.Values._
import scaladex.core.util.ScalaExtensions._
import scaladex.server.route.Badges.summaryOfLatestVersions

class BadgesTests extends ControllerBaseSuite with BeforeAndAfterAll {

Expand All @@ -22,17 +25,6 @@ class BadgesTests extends ControllerBaseSuite with BeforeAndAfterAll {
def insertCats(): Future[Unit] =
Cats.allArtifacts.map(database.insertArtifact(_, Seq.empty, now)).sequence.map(_ => ())

it("should provide a concise summary of latest versions") {
Badges.summaryOfLatestVersions(
Map(
`2.11` -> Seq(`7.0.0`, `7.1.0`),
`2.12` -> Seq(`7.0.0`, `7.1.0`, `7.2.0`),
`2.13` -> Seq(`7.0.0`, `7.1.0`, `7.2.0`, `7.3.0`),
`3` -> Seq(`7.2.0`, `7.3.0`)
)
) shouldBe "7.3.0 (Scala 3.x, 2.13), 7.2.0 (Scala 2.12), 7.1.0 (Scala 2.11)"
}

it("should fallback to JVM artifacts") {
Get(s"/${Cats.reference}/cats-core/latest-by-scala-version.svg") ~> badgesRoute ~> check {
status shouldEqual StatusCodes.TemporaryRedirect
Expand Down Expand Up @@ -73,3 +65,27 @@ class BadgesTests extends ControllerBaseSuite with BeforeAndAfterAll {
}
}
}

class BadgesUnitTests extends AnyFunSpec with Matchers {
it("should provide a concise summary of latest versions") {
summaryOfLatestVersions(
Map(
`2.11` -> Seq(`7.0.0`, `7.1.0`),
`2.12` -> Seq(`7.0.0`, `7.1.0`, `7.2.0`),
`2.13` -> Seq(`7.0.0`, `7.1.0`, `7.2.0`, `7.3.0`),
`3` -> Seq(`7.2.0`, `7.3.0`)
)
) shouldBe "7.3.0 (Scala 3.x, 2.13), 7.2.0 (Scala 2.12), 7.1.0 (Scala 2.11)"
}

it("should prefer releases to pre-releases if both are available") {
summaryOfLatestVersions(Map(`2.13` -> Seq(`7.0.0`, `7.1.0`, `7.2.0-PREVIEW.1`))) shouldBe "7.1.0 (Scala 2.13)"
}

it("should display latest pre-release if no full release is available") {
summaryOfLatestVersions(
Map(`2.13` -> Seq(`7.2.0-PREVIEW.1`, `7.2.0-PREVIEW.2`))
) shouldBe s"${`7.2.0-PREVIEW.2`} (Scala 2.13)"
}

}

0 comments on commit 8b27462

Please sign in to comment.