Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for sbt 2 pre-release and final #1486

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`))
}
}