Skip to content

Commit

Permalink
Merge pull request #1410 from adpi2/project-binary-versions
Browse files Browse the repository at this point in the history
Only show latest Scala versions and latest platforms in search page and project header
  • Loading branch information
adpi2 authored May 30, 2024
2 parents 73045dc + 82dbe6f commit a69467e
Show file tree
Hide file tree
Showing 22 changed files with 149 additions and 140 deletions.
Original file line number Diff line number Diff line change
@@ -1,45 +1,34 @@
package scaladex.view.model

import scaladex.core.model.Artifact
import scaladex.core.model.BinaryVersion
import scaladex.core.model.Language
import scaladex.core.model.MillPlugin
import scaladex.core.model.Platform
import scaladex.core.model.Project
import scaladex.core.model.SbtPlugin
import scaladex.core.model.Scala
import scaladex.core.model.ScalaJs
import scaladex.core.model.ScalaNative
import scaladex.core.model.SemanticVersion
package scaladex.core.model

object ProjectHeader {
def apply(
ref: Project.Reference,
latestArtifacts: Seq[Artifact],
artifacts: Seq[Artifact],
versionCount: Long,
defaultArtifactName: Option[Artifact.Name],
preferStableVersion: Boolean
): Option[ProjectHeader] =
Option.when(latestArtifacts.nonEmpty) {
new ProjectHeader(ref, latestArtifacts, versionCount, defaultArtifactName, preferStableVersion)
Option.when(artifacts.nonEmpty) {
new ProjectHeader(ref, artifacts, versionCount, defaultArtifactName, preferStableVersion)
}
}

final case class ProjectHeader(
ref: Project.Reference,
latestArtifacts: Seq[Artifact],
artifacts: Seq[Artifact],
versionCount: Long,
defaultArtifactName: Option[Artifact.Name],
preferStableVersion: Boolean
) {
def artifactNames: Seq[Artifact.Name] = latestArtifacts.map(_.artifactName).distinct.sorted
def languages: Seq[Language] = latestArtifacts.map(_.language).distinct.sorted
def platforms: Seq[Platform] = latestArtifacts.map(_.platform).distinct.sorted
lazy val defaultArtifact: Artifact = getDefaultArtifact(None, None)
lazy val latestVersion: SemanticVersion = defaultArtifact.version
lazy val latestArtifacts: Seq[Artifact] = artifacts.filter(_.version == latestVersion)
lazy val latestLanguages: Seq[Language] = latestArtifacts.map(_.language).distinct.sorted
lazy val latestPlatforms: Seq[Platform] = latestArtifacts.map(_.platform).distinct.sorted

def allArtifactNames: Seq[Artifact.Name] = artifacts.map(_.artifactName).distinct.sorted
def platforms(artifactName: Artifact.Name): Seq[Platform] =
latestArtifacts.filter(_.artifactName == artifactName).map(_.platform).distinct.sorted(Platform.ordering.reverse)

def defaultVersion: SemanticVersion = getDefaultArtifact(None, None).version
artifacts.filter(_.artifactName == artifactName).map(_.platform).distinct.sorted(Platform.ordering.reverse)

def artifactsUrl: String = artifactsUrl(getDefaultArtifact(None, None), withBinaryVersion = false)

Expand All @@ -56,17 +45,17 @@ final case class ProjectHeader(
}

def getDefaultArtifact(language: Option[Language], platform: Option[Platform]): Artifact = {
val artifacts = latestArtifacts
val filteredArtifacts = artifacts
.filter(artifact => language.forall(_ == artifact.language) && platform.forall(_ == artifact.platform))
val stableArtifacts = artifacts.filter(_.version.isStable)
val stableArtifacts = filteredArtifacts.filter(_.version.isStable)

def byName(artifacts: Seq[Artifact]): Option[Artifact] =
defaultArtifactName.toSeq
.flatMap(defaultName => artifacts.filter(a => defaultName == a.artifactName))
.maxByOption(_.binaryVersion)

def ofVersion(version: SemanticVersion): Artifact =
artifacts
filteredArtifacts
.filter(_.version == version)
.maxBy(a => (a.binaryVersion, a.artifactName))(
Ordering.Tuple2(Ordering[BinaryVersion], Ordering[Artifact.Name].reverse)
Expand All @@ -78,18 +67,18 @@ final case class ProjectHeader(

if (preferStableVersion) {
byName(stableArtifacts)
.orElse(byName(artifacts))
.orElse(byName(filteredArtifacts))
.orElse(byLatestVersion(stableArtifacts))
.orElse(byLatestVersion(artifacts))
.orElse(byLatestVersion(filteredArtifacts))
.get
} else {
byName(artifacts).orElse(byLatestVersion(artifacts)).get
byName(filteredArtifacts).orElse(byLatestVersion(filteredArtifacts)).get
}
}

def scalaVersions: Seq[Scala] = languages.collect { case v: Scala => v }
def scalaJsVersions: Seq[ScalaJs] = platforms.collect { case v: ScalaJs => v }
def scalaNativeVersions: Seq[ScalaNative] = platforms.collect { case v: ScalaNative => v }
def sbtVersions: Seq[SbtPlugin] = platforms.collect { case v: SbtPlugin => v }
def millVersions: Seq[MillPlugin] = platforms.collect { case v: MillPlugin => v }
def latestScalaVersions: Seq[Scala] = latestLanguages.collect { case v: Scala => v }
def latestScalaJsVersions: Seq[ScalaJs] = latestPlatforms.collect { case v: ScalaJs => v }
def latestScalaNativeVersions: Seq[ScalaNative] = latestPlatforms.collect { case v: ScalaNative => v }
def latestSbtVersions: Seq[SbtPlugin] = latestPlatforms.collect { case v: SbtPlugin => v }
def latestMillVersions: Seq[MillPlugin] = latestPlatforms.collect { case v: MillPlugin => v }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,7 @@ package scaladex.core.model.search

import java.time.Instant

import scaladex.core.model.Artifact
import scaladex.core.model.Category
import scaladex.core.model.Language
import scaladex.core.model.MillPlugin
import scaladex.core.model.Platform
import scaladex.core.model.Project
import scaladex.core.model.SbtPlugin
import scaladex.core.model.Scala
import scaladex.core.model.ScalaJs
import scaladex.core.model.ScalaNative
import scaladex.core.model._

// Project document indexed by the search engine
final case class ProjectDocument(
Expand All @@ -24,6 +15,7 @@ final case class ProjectDocument(
updateDate: Option[Instant],
languages: Seq[Language],
platforms: Seq[Platform],
latestVersion: Option[SemanticVersion],
dependents: Long,
category: Option[Category],
formerReferences: Seq[Project.Reference],
Expand All @@ -50,6 +42,7 @@ object ProjectDocument {
None,
Seq.empty,
Seq.empty,
None,
0,
None,
Seq.empty,
Expand All @@ -58,29 +51,25 @@ object ProjectDocument {

def apply(
project: Project,
artifacts: Seq[Artifact],
header: Option[ProjectHeader],
dependents: Long,
formerReferences: Seq[Project.Reference]
): ProjectDocument = {
val (deprecatedArtifactNames, artifactNames) =
artifacts
.map(_.artifactName)
.distinct
.sorted
.partition(project.settings.deprecatedArtifacts.contains)
import project._
header.toSeq.flatMap(_.allArtifactNames).partition(project.settings.deprecatedArtifacts.contains)
ProjectDocument(
organization,
repository,
project.organization,
project.repository,
artifactNames,
deprecatedArtifactNames,
hasCli,
creationDate,
project.hasCli,
project.creationDate,
updateDate = None,
artifacts.map(_.binaryVersion.language).distinct.sorted,
artifacts.map(_.binaryVersion.platform).distinct.sorted,
header.toSeq.flatMap(_.latestLanguages),
header.toSeq.flatMap(_.latestPlatforms),
header.map(_.latestVersion),
dependents,
settings.category,
project.settings.category,
formerReferences,
project.githubInfo.map(_.toDocument)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package scaladex.core.service

import scala.concurrent.ExecutionContext
import scala.concurrent.Future

import scaladex.core.model._

class ProjectService(database: WebDatabase)(implicit context: ExecutionContext) {
def getProjectHeader(project: Project): Future[Option[ProjectHeader]] = {
val ref = project.reference
for {
latestArtifacts <- database.getLatestArtifacts(ref, project.settings.preferStableVersion)
versionCount <- database.countVersions(ref)
} yield ProjectHeader(
project.reference,
latestArtifacts,
versionCount,
project.settings.defaultArtifact,
project.settings.preferStableVersion
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,7 @@ import java.util.UUID

import scala.concurrent.Future

import scaladex.core.model.Artifact
import scaladex.core.model.ArtifactDependency
import scaladex.core.model.GithubInfo
import scaladex.core.model.GithubStatus
import scaladex.core.model.Language
import scaladex.core.model.Platform
import scaladex.core.model.Project
import scaladex.core.model.ProjectDependency
import scaladex.core.model.SemanticVersion
import scaladex.core.model.UserInfo
import scaladex.core.model.UserState
import scaladex.core.model._
import scaladex.core.web.ArtifactsPageParams

trait WebDatabase {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package scaladex.view.model
package scaladex.core.model

import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers
Expand Down
25 changes: 22 additions & 3 deletions modules/core/shared/src/test/scala/scaladex/core/test/Values.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import scaladex.core.model.MajorVersion
import scaladex.core.model.PatchVersion
import scaladex.core.model.Project
import scaladex.core.model.Project.Settings
import scaladex.core.model.ProjectHeader
import scaladex.core.model.Scala
import scaladex.core.model.ScalaJs
import scaladex.core.model.ScalaNative
Expand Down Expand Up @@ -88,8 +89,20 @@ object Values {
val project: Project =
Project.default(reference, None, Some(githubInfo), Some(settings), now = now)

val projectHeader: ProjectHeader = ProjectHeader(
reference,
Seq(artifact),
1,
settings.defaultArtifact,
settings.preferStableVersion
).get
val projectDocument: ProjectDocument =
ProjectDocument(project.copy(creationDate = Some(now.minus(1, ChronoUnit.MINUTES))), Seq(artifact), 0, Seq.empty)
ProjectDocument(
project.copy(creationDate = Some(now.minus(1, ChronoUnit.MINUTES))),
Some(projectHeader),
0,
Seq.empty
)
}

object PlayJsonExtra {
Expand Down Expand Up @@ -231,9 +244,15 @@ object Values {
Scope("compile")
)
)

val versionCount: Int = allArtifacts.map(_.version).distinct.size
val projectHeader: ProjectHeader = ProjectHeader(reference, allArtifacts, versionCount, None, true).get
val projectDocument: ProjectDocument =
ProjectDocument(project.copy(creationDate = Some(now.minus(10, ChronoUnit.MINUTES))), allArtifacts, 1, Seq.empty)
ProjectDocument(
project.copy(creationDate = Some(now.minus(10, ChronoUnit.MINUTES))),
Some(projectHeader),
1,
Seq.empty
)
}

object CatsEffect {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ object ElasticsearchMapping {
dateField("creationDate"),
keywordField("languages"),
keywordField("platforms"),
keywordField("latestVersion"),
intField("dependents"),
keywordField("category"),
textField("githubInfo.description").analyzer("english"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import scaladex.core.model.Category
import scaladex.core.model.Language
import scaladex.core.model.Platform
import scaladex.core.model.Project
import scaladex.core.model.SemanticVersion
import scaladex.core.model.search.GithubInfoDocument
import scaladex.core.model.search.ProjectDocument

Expand All @@ -26,6 +27,7 @@ case class RawProjectDocument(
updateDate: Option[Instant],
languages: Seq[String],
platforms: Seq[String],
latestVersion: Option[String],
dependents: Long,
category: Option[String],
formerReferences: Seq[Project.Reference],
Expand All @@ -41,6 +43,7 @@ case class RawProjectDocument(
updateDate,
languages.flatMap(Language.fromLabel).sorted,
platforms.flatMap(Platform.fromLabel).sorted,
latestVersion.flatMap(SemanticVersion.parse),
dependents,
category.flatMap(Category.byLabel.get),
formerReferences,
Expand All @@ -66,6 +69,7 @@ object RawProjectDocument {
updateDate,
languages.map(_.label),
platforms.map(_.label),
latestVersion.map(_.encode),
dependents,
category.map(_.label),
formerReferences,
Expand Down
12 changes: 7 additions & 5 deletions modules/server/src/it/scala/scaladex/RelevanceTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import scaladex.infra.sql.DoobieUtils
import scaladex.server.service.SearchSynchronizer
import scaladex.core.model.search.PageParams
import scaladex.server.service.DependencyUpdater
import scaladex.core.service.ProjectService

class RelevanceTest extends TestKit(ActorSystem("SbtActorTest")) with AsyncFunSuiteLike with BeforeAndAfterAll {

Expand All @@ -36,7 +37,8 @@ class RelevanceTest extends TestKit(ActorSystem("SbtActorTest")) with AsyncFunSu
val database = new SqlDatabase(datasource, xa)
val filesystem = FilesystemStorage(config.filesystem)

val searchSync = new SearchSynchronizer(database, searchEngine)
val projectService = new ProjectService(database)
val searchSync = new SearchSynchronizer(database, projectService, searchEngine)
val projectDependenciesUpdater = new DependencyUpdater(database)

IO.fromFuture(IO {
Expand Down Expand Up @@ -111,9 +113,9 @@ class RelevanceTest extends TestKit(ActorSystem("SbtActorTest")) with AsyncFunSu
)
}

test("filter _sjs0.6_2.12") {
test("filter _sjs1_2.13") {
top(
SearchParams(languages = Seq("2.12"), platforms = Seq("sjs0.6")),
SearchParams(languages = Seq("2.13"), platforms = Seq("sjs1")),
List(
"scala-js" -> "scala-js"
)
Expand All @@ -131,9 +133,9 @@ class RelevanceTest extends TestKit(ActorSystem("SbtActorTest")) with AsyncFunSu
)
}

test("filter _native0.3_2.11") {
test("filter _native0.4_2.13") {
top(
SearchParams(languages = Seq("2.11"), platforms = Seq("native0.3")),
SearchParams(languages = Seq("2.13"), platforms = Seq("native0.4")),
List(
("scalaz", "scalaz"),
("scopt", "scopt"),
Expand Down
Loading

0 comments on commit a69467e

Please sign in to comment.