Skip to content

Commit 662abd6

Browse files
authored
Scala3 migration (#15)
* Add basic config to proyect, fix DataExplorerSettings issue and basic SpraConfig * TableSettings config * Implement SpraConfig into DataExplorerConfig * CORS * Fix filter and add more examples * Minor changes * Remove space * .sbt config * Fix minor errors * Optimize imports * Fix web compilation * Minor changes
1 parent 41a4542 commit 662abd6

File tree

26 files changed

+65
-82
lines changed

26 files changed

+65
-82
lines changed

.scalafmt.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ project.git = true
33
project.excludeFilters = [
44
]
55

6-
runner.dialect=scala213
6+
runner.dialect=scala3
77

88
maxColumn = 120
99
assumeStandardLibraryStripMargin = false

build.sbt

+17-31
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import java.nio.file.StandardCopyOption.REPLACE_EXISTING
44
ThisBuild / versionScheme := Some("early-semver")
55
// For all Sonatype accounts created on or after February 2021
66
ThisBuild / sonatypeCredentialHost := "s01.oss.sonatype.org"
7+
ThisBuild / scalaVersion := "3.3.0"
78

89
inThisBuild(
910
List(
1011
organization := "net.wiringbits",
1112
name := "scala-postgres-react-admin",
13+
scalaVersion := "3.3.0",
1214
homepage := Some(url("https://github.com/wiringbits/scala-postgres-react-admin")),
1315
licenses := List("MIT" -> url("https://www.opensource.org/licenses/mit-license.html")),
1416
developers := List(
@@ -24,8 +26,12 @@ inThisBuild(
2426

2527
resolvers += Resolver.sonatypeRepo("releases")
2628

27-
val playJson = "2.10.0-RC5"
29+
val play = "2.9.0-M6"
30+
val playJson = "2.10.0-RC9"
2831
val sttp = "3.5.0"
32+
val anorm = "2.7.0"
33+
val scalaTestPlusPlay = "6.0.0-M6"
34+
val scalaTestPlusMockito = "3.2.15.0"
2935

3036
val consoleDisabledOptions = Seq("-Xfatal-warnings", "-Ywarn-unused", "-Ywarn-unused-import")
3137

@@ -35,8 +41,7 @@ lazy val build = TaskKey[File]("build")
3541
lazy val baseServerSettings: Project => Project = {
3642
_.settings(
3743
scalacOptions ++= Seq(
38-
"-unchecked",
39-
"-deprecation",
44+
"-Werror",
4045
"-feature"
4146
),
4247
Compile / doc / scalacOptions ++= Seq("-no-link-warnings"),
@@ -55,18 +60,15 @@ lazy val playSettings: Project => Project = {
5560
Compile / doc / scalacOptions ++= Seq(
5661
"-no-link-warnings"
5762
),
58-
// remove play noisy warnings
59-
play.sbt.routes.RoutesKeys.routesImport := Seq.empty,
6063
libraryDependencies ++= Seq(
6164
evolutions,
62-
"com.typesafe.play" %% "play-jdbc" % "2.8.13",
65+
"com.typesafe.play" %% "play-jdbc" % "2.9.0-M6",
6366
"com.google.inject" % "guice" % "5.1.0"
6467
),
6568
// test
6669
libraryDependencies ++= Seq(
67-
"org.scalatestplus.play" %% "scalatestplus-play" % "5.1.0" % Test,
68-
"org.mockito" %% "mockito-scala" % "1.17.5" % Test,
69-
"org.mockito" %% "mockito-scala-scalatest" % "1.17.5" % Test
70+
"org.scalatestplus.play" %% "scalatestplus-play" % "6.0.0-M6" % Test,
71+
"org.scalatestplus" %% "mockito-4-6" % scalaTestPlusMockito % Test
7072
)
7173
)
7274
}
@@ -105,11 +107,6 @@ lazy val baseLibSettings: Project => Project = _.settings(
105107
// The common stuff for the server/client modules
106108
lazy val spraCommon = (crossProject(JSPlatform, JVMPlatform) in file("spra-common"))
107109
.configure(baseLibSettings)
108-
.settings(
109-
scalaVersion := "2.13.8",
110-
crossScalaVersions := Seq("2.13.8", "3.1.2"),
111-
name := "spra-common"
112-
)
113110
.jsConfigure(_.enablePlugins(ScalaJSPlugin, ScalaJSBundlerPlugin))
114111
.jvmSettings(
115112
libraryDependencies ++= Seq(
@@ -131,11 +128,6 @@ lazy val spraCommon = (crossProject(JSPlatform, JVMPlatform) in file("spra-commo
131128
lazy val spraApi = (crossProject(JSPlatform, JVMPlatform) in file("spra-api"))
132129
.configure(baseLibSettings)
133130
.dependsOn(spraCommon)
134-
.settings(
135-
scalaVersion := "2.13.8",
136-
crossScalaVersions := Seq("2.13.8", "3.1.2"),
137-
name := "spra-api"
138-
)
139131
.jsConfigure(_.enablePlugins(ScalaJSPlugin, ScalaJSBundlerPlugin))
140132
.jvmSettings(
141133
libraryDependencies ++= Seq(
@@ -156,19 +148,16 @@ lazy val spraApi = (crossProject(JSPlatform, JVMPlatform) in file("spra-api"))
156148
/** Includes the specific stuff to run the SPRA server side (play-specific)
157149
*/
158150
lazy val spraPlayServer = (project in file("spra-play-server"))
151+
.enablePlugins(PlayScala)
159152
.dependsOn(spraApi.jvm, spraCommon.jvm)
160153
.configure(baseServerSettings, playSettings)
161154
.settings(
162-
scalaVersion := "2.13.8",
163-
crossScalaVersions := Seq("2.13.8"),
164-
name := "spra-play-server",
165155
fork := true,
166156
Test / fork := true, // allows for graceful shutdown of containers once the tests have finished running
167157
libraryDependencies ++= Seq(
168158
guice,
169-
"org.playframework.anorm" %% "anorm" % "2.6.10",
170-
"com.typesafe.play" %% "play" % "2.8.13",
171-
"com.typesafe.play" %% "play-json" % "2.9.2",
159+
"org.playframework.anorm" %% "anorm" % anorm,
160+
"com.typesafe.play" %% "play-json" % playJson,
172161
"org.postgresql" % "postgresql" % "42.3.6",
173162
"com.github.jwt-scala" %% "jwt-core" % "9.0.5",
174163
"de.svenkubiak" % "jBCrypt" % "0.4.3",
@@ -254,22 +243,19 @@ lazy val browserProject: Project => Project =
254243
)
255244

256245
lazy val spraWeb = (project in file("spra-web"))
257-
.dependsOn(spraApi.js, spraPlayServer)
246+
.dependsOn(spraApi.js)
258247
.configure(bundlerSettings, baseLibSettings, browserProject, spraWebBuildInfoSettings)
259248
.configure(_.enablePlugins(ScalaJSPlugin, ScalaJSBundlerPlugin))
260249
.settings(
261-
scalaVersion := "2.13.8",
262-
crossScalaVersions := Seq("2.13.8", "3.1.2"),
263-
name := "spra-web",
264250
Test / fork := false, // sjs needs this to run tests
265251
scalaJSUseMainModuleInitializer := true,
266252
scalaJSLinkerConfig := scalaJSLinkerConfig.value.withSourceMap(false),
267253
webpackDevServerPort := 8081,
268254
webpackBundlingMode := BundlingMode.LibraryOnly(),
269255
libraryDependencies ++= Seq(
270256
"org.scala-js" %%% "scala-js-macrotask-executor" % "1.0.0",
271-
"me.shadaj" %%% "slinky-core" % "0.7.3",
272-
"me.shadaj" %%% "slinky-web" % "0.7.3"
257+
"me.shadaj" %%% "slinky-core" % "0.7.4",
258+
"me.shadaj" %%% "slinky-web" % "0.7.4"
273259
),
274260
Compile / npmDependencies ++= Seq(
275261
"react" -> "17.0.0",

project/plugins.sbt

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0")
1+
// while there are some eviction errors, plugins seem to be compatible so far
2+
evictionErrorLevel := sbt.util.Level.Warn
23

3-
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.13")
4+
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.1")
45

5-
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.8.0")
6+
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.9.0-M6")
7+
8+
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.13.1")
69

710
addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.20.0")
811

spra-api/shared/src/main/scala/net/wiringbits/spra/api/AdminDataExplorerApiClient.scala

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
package net.wiringbits.spra.api
22

3-
import net.wiringbits.spra.api.models.{
4-
AdminCreateTable,
5-
AdminDeleteTable,
6-
AdminGetTables,
7-
AdminUpdateTable,
8-
PlayErrorResponse
9-
}
10-
import net.wiringbits.spra.api.models._
11-
import play.api.libs.json._
12-
import sttp.client3._
13-
import sttp.model._
3+
import net.wiringbits.spra.api.models.*
4+
import play.api.libs.json.*
5+
import sttp.client3.*
6+
import sttp.model.*
147

158
import scala.concurrent.{ExecutionContext, Future}
169
import scala.util.{Failure, Success, Try}

spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/package.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package net.wiringbits.spra.api
22

3-
import play.api.libs.json._
3+
import play.api.libs.json.*
44

55
import java.time.Instant
66

spra-play-server/src/main/resources/routes

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
# https://www.playframework.com/documentation/latest/ScalaRouting
44
# ~~~~
55

6-
-> / net.wiringbits.spra.admin.AppRouter
6+
-> / net.wiringbits.spra.admin.AppRouter

spra-play-server/src/main/scala/net/wiringbits/spra/admin/AppRouter.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import net.wiringbits.spra.admin.utils.StringToDataTypesExt
55
import net.wiringbits.spra.admin.utils.models.{FilterParameter, PaginationParameter, QueryParameters, SortParameter}
66
import play.api.routing.Router.Routes
77
import play.api.routing.SimpleRouter
8-
import play.api.routing.sird._
8+
import play.api.routing.sird.*
99

1010
import javax.inject.Inject
1111

spra-play-server/src/main/scala/net/wiringbits/spra/admin/config/TableSettings.scala

+5-10
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ case class TableSettings(
4545

4646
object TableSettings {
4747
implicit val configLoader: ConfigLoader[TableSettings] = (config: Config, path: String) => {
48-
import scala.jdk.CollectionConverters._
48+
import scala.jdk.CollectionConverters.*
4949
val newConfig = config.getConfig(path)
5050

5151
def get[A](path: String): A = {
@@ -97,16 +97,11 @@ object TableSettings {
9797
}
9898
}
9999

100-
sealed trait PrimaryKeyDataType extends Product with Serializable
101-
object PrimaryKeyDataType {
102-
final case object UUID extends PrimaryKeyDataType
103-
final case object Serial extends PrimaryKeyDataType
104-
final case object BigSerial extends PrimaryKeyDataType
100+
enum PrimaryKeyDataType {
101+
case UUID, Serial, BigSerial
105102
}
106103

107-
sealed trait CustomDataType extends Product with Serializable
108-
object CustomDataType {
109-
final case object BinaryImage extends CustomDataType
104+
enum CustomDataType {
110105
// TODO: add support to binary files
111-
final case object Binary extends CustomDataType
106+
case BinaryImage, Binary
112107
}

spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package net.wiringbits.spra.admin.controllers
33
import net.wiringbits.spra.admin.config.DataExplorerConfig
44
import net.wiringbits.spra.admin.services.AdminService
55
import net.wiringbits.spra.admin.utils.models.QueryParameters
6-
import net.wiringbits.spra.api.models._
6+
import net.wiringbits.spra.api.models.*
77
import org.slf4j.LoggerFactory
88
import play.api.libs.json.Json
99
import play.api.mvc.{AbstractController, ControllerComponents}
@@ -32,7 +32,8 @@ class AdminController @Inject() (
3232
_ <- adminUser(request)
3333
_ = logger.info(s"Get metadata for $tableName, parameters: $queryParams")
3434
(response, contentRange) <- adminService.tableMetadata(tableName, queryParams)
35-
} yield Ok(Json.toJson(response))
35+
// Json.toJson doesn't support a List[Map[_, _]] so we need to map to convert it to List[JsonValue]
36+
} yield Ok(Json.toJson(response.map(Json.toJson(_))))
3637
.withHeaders(("Access-Control-Expose-Headers", "Content-Range"), ("Content-Range", contentRange))
3738
}
3839

@@ -49,7 +50,7 @@ class AdminController @Inject() (
4950
_ <- adminUser(request)
5051
_ = logger.info(s"Get data from $tableName where primaryKeys = ${primaryKeyValues.mkString(",")}")
5152
response <- adminService.find(tableName, primaryKeyValues)
52-
} yield Ok(Json.toJson(response))
53+
} yield Ok(Json.toJson(response.map(Json.toJson(_))))
5354
}
5455

5556
def create(tableName: String) = handleJsonBody[AdminCreateTable.Request] { request =>

spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/package.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package net.wiringbits.spra.admin
22

3-
import net.wiringbits.spra.api.models.ErrorResponse
3+
import net.wiringbits.spra.api.models.{ErrorResponse, errorResponseFormat}
44
import org.slf4j.LoggerFactory
55
import play.api.libs.json.{JsValue, Json, Reads}
6+
import play.api.mvc.*
67
import play.api.mvc.Results.InternalServerError
7-
import play.api.mvc._
88

99
import scala.concurrent.{ExecutionContext, Future}
1010
import scala.util.control.NonFatal

spra-play-server/src/main/scala/net/wiringbits/spra/admin/repositories/daos/DatabaseTablesDAO.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package net.wiringbits.spra.admin.repositories.daos
22

33
import anorm.{SqlParser, SqlStringInterpolation}
44
import net.wiringbits.spra.admin.config.{CustomDataType, PrimaryKeyDataType, TableSettings}
5-
import net.wiringbits.spra.admin.repositories.models._
5+
import net.wiringbits.spra.admin.repositories.models.*
66
import net.wiringbits.spra.admin.utils.models.{FilterParameter, QueryParameters}
77
import net.wiringbits.spra.admin.utils.{QueryBuilder, StringRegex}
88

spra-play-server/src/main/scala/net/wiringbits/spra/admin/repositories/daos/package.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package net.wiringbits.spra.admin.repositories
22

3-
import anorm._
3+
import anorm.*
44
import net.wiringbits.spra.admin.repositories.models.{DatabaseTable, ForeignKey, TableColumn}
55

66
package object daos {

spra-play-server/src/main/scala/net/wiringbits/spra/admin/services/AdminService.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import net.wiringbits.spra.admin.repositories.DatabaseTablesRepository
55
import net.wiringbits.spra.admin.repositories.models.{ForeignKey, TableData}
66
import net.wiringbits.spra.admin.utils.models.QueryParameters
77
import net.wiringbits.spra.admin.utils.{MapStringHideExt, contentRangeHeader}
8-
import net.wiringbits.spra.api.models._
8+
import net.wiringbits.spra.api.models.*
99

1010
import java.awt.image.BufferedImage
1111
import java.io.{ByteArrayInputStream, File}

spra-play-server/src/test/scala/controllers/AdminControllerSpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ class AdminControllerSpec extends PlayPostgresSpec {
311311
val nameLength = 7
312312
Range.apply(0, createdUsers).foreach { i =>
313313
val letter = Character.valueOf(('A' + i).toChar)
314-
val name = StringUtils.repeat(letter, nameLength);
314+
val name = StringUtils.repeat(letter, nameLength)
315315
val data = Map("name" -> name, "email" -> s"test@wiringbits$i.net", "password" -> "wiringbits")
316316
val request = AdminCreateTable.Request(data)
317317
client.createItem(usersSettings.tableName, request).futureValue

spra-play-server/src/test/scala/controllers/common/PlayAPISpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory
66
import play.api.inject.guice.GuiceApplicationBuilder
77
import play.api.mvc.Result
88
import play.api.test.FakeRequest
9-
import play.api.test.Helpers._
9+
import play.api.test.Helpers.*
1010
import play.api.{Application, Mode}
1111

1212
import java.net.URLEncoder

spra-play-server/src/test/scala/controllers/common/PlayPostgresSpec.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import org.scalatestplus.play.guice.GuiceOneServerPerTest
99
import org.testcontainers.utility.DockerImageName
1010
import play.api.inject.guice.GuiceApplicationBuilder
1111
import play.api.{Application, Configuration, Environment, Mode}
12+
import sttp.client3.SttpBackend
1213

1314
import scala.concurrent.{ExecutionContext, Future}
1415
import scala.util.control.NonFatal
@@ -47,7 +48,7 @@ trait PlayPostgresSpec extends PlayAPISpec with TestContainerForEach with GuiceO
4748
def withApiClient[A](runTest: AdminDataExplorerApiClient => A): A = {
4849
import sttp.client3.asynchttpclient.future.AsyncHttpClientFutureBackend
4950

50-
implicit val sttpBackend = AsyncHttpClientFutureBackend()
51+
implicit val sttpBackend: SttpBackend[Future, Any] = AsyncHttpClientFutureBackend()
5152

5253
val config = AdminDataExplorerApiClient.Config(s"http://localhost:$port")
5354
val client = new AdminDataExplorerApiClient.DefaultImpl(config)

spra-play-server/src/test/scala/net/wiringbits/spra/admin/QueryBuilderSpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package net.wiringbits.spra.admin
22

33
import net.wiringbits.spra.admin.repositories.models.TableColumn
44
import net.wiringbits.spra.admin.utils.QueryBuilder
5-
import org.scalatest.matchers.must.Matchers.{be, convertToAnyMustWrapper}
5+
import org.scalatest.matchers.must.Matchers.{be, must}
66
import org.scalatest.wordspec.AnyWordSpec
77

88
class QueryBuilderSpec extends AnyWordSpec {

spra-play-server/src/test/scala/net/wiringbits/spra/admin/StringRegexSpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package net.wiringbits.spra.admin
22

33
import net.wiringbits.spra.admin.utils.StringRegex
4-
import org.scalatest.matchers.must.Matchers.{be, convertToAnyMustWrapper}
4+
import org.scalatest.matchers.must.Matchers.{be, must}
55
import org.scalatest.wordspec.AnyWordSpec
66

77
class StringRegexSpec extends AnyWordSpec {

spra-play-server/src/test/scala/net/wiringbits/spra/admin/UtilsSpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package net.wiringbits.spra.admin
22

33
import net.wiringbits.spra.admin.utils.StringToDataTypesExt
44
import org.scalatest.OptionValues.convertOptionToValuable
5-
import org.scalatest.matchers.must.Matchers.{be, convertToAnyMustWrapper}
5+
import org.scalatest.matchers.must.Matchers.{be, must}
66
import org.scalatest.wordspec.AnyWordSpec
77

88
class UtilsSpec extends AnyWordSpec {

spra-play-server/src/test/scala/net/wiringbits/spra/admin/models/FilterParameterSpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package net.wiringbits.spra.admin.models
22

33
import net.wiringbits.spra.admin.utils.models.FilterParameter
4-
import org.scalatest.matchers.must.Matchers.{be, convertToAnyMustWrapper}
4+
import org.scalatest.matchers.must.Matchers.{be, must}
55
import org.scalatest.wordspec.AnyWordSpec
66

77
class FilterParameterSpec extends AnyWordSpec {

spra-play-server/src/test/scala/net/wiringbits/spra/admin/models/PaginationParameterSpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package net.wiringbits.spra.admin.models
22

33
import net.wiringbits.spra.admin.utils.models.PaginationParameter
4-
import org.scalatest.matchers.must.Matchers.{be, convertToAnyMustWrapper}
4+
import org.scalatest.matchers.must.Matchers.{be, must}
55
import org.scalatest.wordspec.AnyWordSpec
66

77
import scala.util.Try

spra-play-server/src/test/scala/net/wiringbits/spra/admin/models/SortParameterSpec.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package net.wiringbits.spra.admin.models
22

33
import net.wiringbits.spra.admin.utils.models.SortParameter
4-
import org.scalatest.matchers.must.Matchers.{be, convertToAnyMustWrapper}
4+
import org.scalatest.matchers.must.Matchers.{be, must}
55
import org.scalatest.wordspec.AnyWordSpec
66

77
class SortParameterSpec extends AnyWordSpec {

spra-web/src/main/js/index.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
You need to enable JavaScript to run this app.
2121
</noscript>
2222
<div id="root"></div>
23-
<script type="text/javascript" src="spra-web-fastopt-library.js"></script>
24-
<script type="text/javascript" src="spra-web-fastopt-loader.js"></script>
25-
<script type="text/javascript" src="spra-web-fastopt.js"></script>
23+
<script type="text/javascript" src="spraweb-fastopt-library.js"></script>
24+
<script type="text/javascript" src="spraweb-fastopt-loader.js"></script>
25+
<script type="text/javascript" src="spraweb-fastopt.js"></script>
2626
</body>
2727

2828
</html>

0 commit comments

Comments
 (0)