Skip to content

Commit

Permalink
Merge pull request #1486 from adpi2/sbt2-support
Browse files Browse the repository at this point in the history
Add support for sbt 2 pre-release and final
  • Loading branch information
adpi2 authored Oct 24, 2024
2 parents 7acc329 + 1fb5bb9 commit baea170
Show file tree
Hide file tree
Showing 14 changed files with 151 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ trait Endpoints

private val platformFilters = qs[Seq[Platform]](
"platform",
qsDoc("Filter on platform versions", Seq("jvm", "sjs1", "native0.5", "sbt1.0", "mill0.11"))
qsDoc("Filter on platform versions", Seq("jvm", "sjs1", "native0.5", "sbt1", "mill0.11"))
)

private val binaryVersionFilters: QueryString[Seq[BinaryVersion]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ object Artifact {

def name: Name = artifactId.name
def binaryVersion: BinaryVersion = artifactId.binaryVersion
def platform: Platform = binaryVersion.platform
def language: Language = binaryVersion.language

def searchUrl: String =
s"https://search.maven.org/#artifactdetails|$groupId|$artifactId|$version|jar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,30 @@ final case class BinaryVersion(platform: Platform, language: Language) {

// non-empty
def value: String = (platform, language) match {
case (Jvm, Java) => language.value
case (Jvm, Scala(sv)) => s"_${sv.value}"
case (SbtPlugin(sbtV), Scala(sv)) => s"_${sv.value}_${sbtV.value}"
case (platform, language) => s"_${platform.value}_${language.value}"
case (Jvm, Java) => language.value
case (Jvm, Scala(sv)) => s"_${sv.value}"
case (SbtPlugin(sbtV), Scala(sv)) =>
sbtV match {
case Version.Major(1) => s"_${sv.value}_1.0"
case Version.Minor(0, 13) => s"_${sv.value}_0.13"
case sbtV => s"_sbt${sbtV.value}_${sv.value}"
}
case (platform, language) => s"_${platform.value}_${language.value}"
}

override def toString: String = (platform, language) match {
case (Jvm, Java) => "Java"
case (Jvm, Scala(version)) => s"Scala $version"
case (_, _) => s"$platform ($language)"
override def toString: String = platform match {
case Jvm => language.toString
case p: SbtPlugin => p.toString
case p: MillPlugin => p.toString
case _ => s"$platform ($language)"
}
}

object BinaryVersion {
implicit val ordering: Ordering[BinaryVersion] = Ordering.by(v => (v.platform, v.language))

def IntermediateParser[A: P]: P[(String, Option[Version], Option[Version])] =
("_sjs" | "_native" | "_mill" | "_" | "").! ~ (Version.SemanticParser.?) ~ ("_" ~ Version.SemanticParser).?
("_sjs" | "_native" | "_mill" | "_sbt" | "_" | "").! ~ (Version.SemanticParser.?) ~ ("_" ~ Version.SemanticParser).?

def IntermediateParserButNotInvalidSbt[A: P]: P[(String, Option[Version], Option[Version])] =
IntermediateParser.filter {
Expand All @@ -46,6 +52,7 @@ object BinaryVersion {
case ("_sjs", Some(jsV), Some(scalaV)) => Some(BinaryVersion(ScalaJs(jsV), Scala(scalaV)))
case ("_native", Some(nativeV), Some(scalaV)) => Some(BinaryVersion(ScalaNative(nativeV), Scala(scalaV)))
case ("_mill", Some(millV), Some(scalaV)) => Some(BinaryVersion(MillPlugin(millV), Scala(scalaV)))
case ("_sbt", Some(sbtV), Some(scalaV)) => Some(BinaryVersion(SbtPlugin(sbtV), Scala(scalaV)))
case ("_", Some(scalaV), Some(sbtV)) => Some(BinaryVersion(SbtPlugin(sbtV), Scala(scalaV)))
case ("_", Some(scalaV), None) => Some(BinaryVersion(Jvm, Scala(scalaV)))
case ("", None, None) => Some(BinaryVersion(Jvm, Java))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ case object Java extends Language {
override def value: String = "java"
override def label: String = toString
override def isValid: Boolean = true
override def toString: String = "Java"
}

final case class Scala(version: Version) extends Language {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,27 @@ object ScalaJs {
}

case class SbtPlugin(version: Version) extends Platform {
override def toString: String =
version match {
case Version.Minor(1, 0) => s"sbt 1.x"
case _ => s"sbt $version"
}
override def toString: String = s"sbt $version"
override def value: String = s"sbt${version.value}"
override def isValid: Boolean = SbtPlugin.stableVersions.contains(this)
override def isValid: Boolean = SbtPlugin.stableVersions.contains(this) || isSbt2PreRelease

private def isSbt2PreRelease: Boolean = version match {
case Version.SemanticLike(2, Some(0), Some(0), None, Some(_), None) => true
case _ => false
}
}

object SbtPlugin {
val `0.13`: SbtPlugin = SbtPlugin(Version(0, 13))
val `1.0`: SbtPlugin = SbtPlugin(Version(1, 0))
val stableVersions: Set[SbtPlugin] = Set(`0.13`, `1.0`)
val `1.x`: SbtPlugin = SbtPlugin(Version(1))
val `2.x`: SbtPlugin = SbtPlugin(Version(2))

def apply(version: Version): SbtPlugin = version match {
case Version.Minor(1, 0) => `1.x`
case _ => new SbtPlugin(version)
}

val stableVersions: Set[SbtPlugin] = Set(`0.13`, `1.x`, `2.x`)

implicit val ordering: Ordering[SbtPlugin] = Ordering.by(p => p.asInstanceOf[Platform])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ object Version {

// We prefer the latest stable artifact.
val PreferStable: Ordering[Version] =
Ordering.by[Version, Boolean](_.isStable).orElse(ordering)
Ordering.by((v: Version) => v.isStable).orElse(ordering)

final case class SemanticLike(
major: Int,
Expand All @@ -44,8 +44,7 @@ object Version {
preRelease: Option[PreRelease] = None,
metadata: Option[String] = None
) extends Version {
override def isSemantic: Boolean =
patch.isDefined && patch2.isEmpty && preRelease.forall(_.isSemantic)
override def isSemantic: Boolean = patch2.isEmpty && preRelease.forall(_.isSemantic)

override def isPreRelease: Boolean = preRelease.isDefined || metadata.isDefined

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ArtifactIdTests extends AsyncFunSpec with Matchers {
it("parses sbt") {
val artifactId = "sbt-microsites_2.12_1.0"
val expected =
ArtifactId(Name("sbt-microsites"), BinaryVersion(SbtPlugin.`1.0`, Scala.`2.12`))
ArtifactId(Name("sbt-microsites"), BinaryVersion(SbtPlugin.`1.x`, Scala.`2.12`))
val result = ArtifactId(artifactId)
result shouldBe expected
result.value shouldBe artifactId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ package scaladex.core

import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers
import scaladex.core.model.Jvm
import scaladex.core.model.MillPlugin
import scaladex.core.model.Platform
import scaladex.core.model.SbtPlugin
import scaladex.core.model.ScalaJs
import scaladex.core.model.ScalaNative
import scaladex.core.model._

class PlatformTests extends AnyFunSpec with Matchers {
it("should yield a Platform from its label") {
it("should parse a Platform from its value") {
Platform.parse("sjs1").get shouldBe ScalaJs.`1.x`
Platform.parse("jvm").get shouldBe Jvm
Platform.parse("native0.4").get shouldBe ScalaNative.`0.4`
Platform.parse("sbt1.0").get shouldBe SbtPlugin.`1.0`
Platform.parse("sbt1.0").get shouldBe SbtPlugin.`1.x`
Platform.parse("sbt1").get shouldBe SbtPlugin.`1.x`
Platform.parse("sbt2.0.0-M2").get shouldBe SbtPlugin(
Version.SemanticLike(2, Some(0), Some(0), preRelease = Some(Milestone(2)))
)
Platform.parse("mill0.10").get shouldBe MillPlugin.`0.10`
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.scalatest.matchers.should.Matchers
import org.scalatest.prop.TableDrivenPropertyChecks
import scaladex.core.test.Values._

class SemanticVersionTests extends AsyncFunSpec with Matchers with TableDrivenPropertyChecks {
class VersionTests extends AsyncFunSpec with Matchers with TableDrivenPropertyChecks {
it("should parse any version") {
val inputs = Table(
("input", "output"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package scaladex.infra.migrations
import com.typesafe.scalalogging.LazyLogging
import doobie.Query0
import doobie.util.update.Update
import org.flywaydb.core.api.migration.BaseJavaMigration
import org.flywaydb.core.api.migration.Context
import scaladex.core.model._
import scaladex.infra.sql.DoobieUtils.Mappings._
import scaladex.infra.sql.DoobieUtils.selectRequest
import scaladex.infra.sql.DoobieUtils.updateRequest

class V25__fix_sbt_platform extends BaseJavaMigration with ScaladexBaseMigration with LazyLogging {
override def migrate(context: Context): Unit =
try {
val request =
for {
artifactRefs <- selectArtifactRefs.to[Seq]
_ <- updatePlatformAndLanguage.updateMany(artifactRefs.map(a => (a.platform, a.language, a)))
} yield ()
run(xa)(request).unsafeRunSync()

} catch {
case e: Throwable =>
logger.info("failed to migrate the database")
throw new Exception(s"failed to migrate the database because of ${e.getMessage}")
}

val selectArtifactRefs: Query0[Artifact.Reference] = selectRequest(
"artifacts",
Seq("group_id", "artifact_id", "version"),
where = Seq("platform='sbt1.0' OR artifact_id LIKE '%_sbt2.0.0-M2_3'")
)

val updatePlatformAndLanguage: Update[(Platform, Language, Artifact.Reference)] =
updateRequest("artifacts", Seq("platform", "language_version"), Seq("group_id", "artifact_id", "version"))

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package scaladex.infra.migrations
import com.typesafe.scalalogging.LazyLogging
import doobie.Query0
import doobie.util.update.Update
import org.flywaydb.core.api.migration.BaseJavaMigration
import org.flywaydb.core.api.migration.Context
import scaladex.core.model._
import scaladex.infra.sql.DoobieUtils.Mappings._
import scaladex.infra.sql.DoobieUtils.selectRequest
import scaladex.infra.sql.DoobieUtils.updateRequest

class V26__fix_artifact_names extends BaseJavaMigration with ScaladexBaseMigration with LazyLogging {
override def migrate(context: Context): Unit =
try {
val request =
for {
artifactRefs <- selectArtifactRefs.to[Seq]
_ <- updateNames.updateMany(artifactRefs.map(a => (a.name, a)))
} yield ()
run(xa)(request).unsafeRunSync()

} catch {
case e: Throwable =>
logger.info("failed to migrate the database")
throw new Exception(s"failed to migrate the database because of ${e.getMessage}")
}

val selectArtifactRefs: Query0[Artifact.Reference] = selectRequest(
"artifacts",
Seq("group_id", "artifact_id", "version"),
where = Seq("artifact_id LIKE '%_sbt2.0.0-M2_3'")
)

val updateNames: Update[(Artifact.Name, Artifact.Reference)] =
updateRequest("artifacts", Seq("artifact_name"), Seq("group_id", "artifact_id", "version"))

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import scaladex.core.model.Version

final case class EcosystemVersion(version: Version, libraryCount: Int, search: Url)

object EcosystemVersion {
val ordering: Ordering[EcosystemVersion] = Ordering.by(_.version)
}

final case class EcosystemHighlight(
ecosystem: String,
currentVersion: EcosystemVersion,
Expand All @@ -17,7 +13,7 @@ final case class EcosystemHighlight(

object EcosystemHighlight {
def apply(ecosystem: String, allVersions: Seq[EcosystemVersion]): Option[EcosystemHighlight] = {
val sortedVersions = allVersions.sorted(EcosystemVersion.ordering.reverse)
val sortedVersions = allVersions.sortBy(_.version)(Version.PreferStable).reverse
sortedVersions.headOption.map(EcosystemHighlight(ecosystem, _, sortedVersions.tail))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@
<div class="float-right">
<form>
<select name="binary-version" class="selectpicker"
data-style="btn-primary" onchange="this.form.submit()">
@for((platform, binaryVersions) <- binaryVersions.groupBy(_.platform)) {
<optgroup label="@platform">
@for(binaryVersion <- binaryVersions.sortBy(_.language)(Language.ordering.reverse)) {
<option value="@binaryVersion.value"
@if(params.binaryVersion.contains(binaryVersion) || artifact.binaryVersion == binaryVersion) {selected}>
@binaryVersion
</option>
}
</optgroup>
}
title="@artifact.binaryVersion" data-selected-text-format="static" data-style="btn-primary" onchange="this.form.submit()">
@for((platform, binaryVersions) <- binaryVersions.groupBy(_.platform).toSeq.sortBy(_._1).reverse) {
<optgroup label="@platform">
@for(binaryVersion <- binaryVersions.sorted.reverse) {
<option value="@binaryVersion.value"
@if(params.binaryVersion.contains(binaryVersion) || artifact.binaryVersion == binaryVersion) {selected}>
@binaryVersion.language.label
</option>
}
</optgroup>
}
</select>
</form>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package scaladex.view.model

import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers
import scaladex.core.model._

class EcosystemHighlightTest extends AnyFunSpec with Matchers {
it("ordering") {
val `1.x` = EcosystemVersion(Version(1), 0, Url(""))
val `0.13` = EcosystemVersion(Version(0, 13), 0, Url(""))
val `2.0.0-M2` =
EcosystemVersion(Version.SemanticLike(2, Some(0), Some(0), preRelease = Some(Milestone(2))), 0, Url(""))

val highlight = EcosystemHighlight("sbt", Seq(`1.x`, `0.13`, `2.0.0-M2`)).get
highlight.currentVersion shouldBe `1.x`
(highlight.otherVersions should contain).theSameElementsInOrderAs(Seq(`0.13`, `2.0.0-M2`))
}
}

0 comments on commit baea170

Please sign in to comment.