Skip to content

Commit 2f57dbe

Browse files
authored
Cross compile with Scala 3 (#931)
1 parent 4ea8cfb commit 2f57dbe

File tree

24 files changed

+141
-64
lines changed

24 files changed

+141
-64
lines changed

.github/workflows/ci.yml

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,52 @@ jobs:
101101
- name: Run tests
102102
id: run-tests
103103
run: SCALA_MAJOR_VERSION=${{ env.scala }} sbt root/test
104+
ci-3:
105+
# run on external PRs, but not on internal PRs since those will be run by push to branch
106+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
107+
runs-on: ubuntu-20.04
108+
env:
109+
scala: 3
110+
steps:
111+
- name: Check-out repository
112+
id: repo-checkout
113+
uses: actions/checkout@v2
114+
115+
- name: Set up JDK
116+
uses: actions/setup-java@v2
117+
with:
118+
distribution: 'temurin'
119+
java-version: 8
120+
121+
- uses: actions/setup-node@v3
122+
with:
123+
node-version: 16
124+
125+
- name: Install AWS cli 1
126+
run: |
127+
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle-1.27.127.zip" -o "awscliv1.zip"
128+
unzip -qq ./awscliv1.zip
129+
sudo ./awscli-bundle/install -i /usr/local/aws1 -b /usr/local/bin/aws1
130+
131+
- name: Install AWS cli 2
132+
run: |
133+
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
134+
unzip -qq ./awscliv2.zip
135+
sudo ./aws/install -i /usr/local/aws2 -b /usr/local/bin/aws2
136+
137+
- name: Cache SBT
138+
id: cache-sbt
139+
uses: actions/cache@v2
140+
with:
141+
path: |
142+
~/.sbt
143+
~/.ivy2/cache
144+
~/.coursier
145+
key: ${{ runner.os }}-sbt-${{ env.scala }}-${{ hashFiles('**/build.sbt') }}
146+
147+
- name: Run tests
148+
id: run-tests
149+
run: SCALA_MAJOR_VERSION=${{ env.scala }} sbt root/test
104150

105151
ci-docker:
106152
# run on external PRs, but not on internal PRs since those will be run by push to branch
@@ -143,7 +189,7 @@ jobs:
143189
run: sbt "project nativeServer; Docker / publishLocal"
144190

145191
publish-jar:
146-
needs: [ci-2-12, ci-2-13, ci-docker]
192+
needs: [ci-2-12, ci-2-13, ci-3, ci-docker]
147193
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v'))
148194
runs-on: ubuntu-20.04
149195
steps:
@@ -202,7 +248,7 @@ jobs:
202248
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
203249

204250
publish-docker:
205-
needs: [ci-2-12, ci-2-13, ci-docker]
251+
needs: [ci-2-12, ci-2-13, ci-3, ci-docker]
206252
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v'))
207253
runs-on: ubuntu-20.04
208254
steps:

build.sbt

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import scala.sys.process.Process
1010

1111
val v2_12 = "2.12.15"
1212
val v2_13 = "2.13.8"
13+
val v3 = "3.3.1"
1314

1415
lazy val resolvedScalaVersion =
1516
sys.env.get("SCALA_MAJOR_VERSION") match {
1617
case Some("2.12") => v2_12
1718
case Some("2.13") => v2_13
19+
case Some("3") => v3
1820
case Some(unsupported) => throw new IllegalArgumentException(s"Unsupported SCALA_MAJOR_VERSION: $unsupported")
1921
case _ => v2_13
2022
}
@@ -26,7 +28,7 @@ lazy val ensureDockerBuildx = taskKey[Unit]("Ensure that docker buildx configura
2628
lazy val dockerBuildWithBuildx = taskKey[Unit]("Build docker images using buildx")
2729

2830
val config = "com.typesafe" % "config" % "1.4.3"
29-
val pureConfig = "com.github.pureconfig" %% "pureconfig" % "0.17.4"
31+
val pureConfig = "com.github.pureconfig" %% "pureconfig-core" % "0.17.4"
3032
val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.2.0"
3133

3234
val scalalogging = "com.typesafe.scala-logging" %% "scala-logging" % "3.9.5"
@@ -55,9 +57,10 @@ val springVersion = "5.3.31"
5557
val awsSpringMessaging = "org.springframework.cloud" % "spring-cloud-aws-messaging" % awsSpringMessagingVersion
5658
val springWeb = "org.springframework" % "spring-web" % springVersion
5759

58-
val scalaAsync = "org.scala-lang.modules" %% "scala-async" % "1.0.1"
60+
val scala2Async = "org.scala-lang.modules" %% "scala-async" % "1.0.1"
61+
val scala3Async = "com.github.rssh" %% "shim-scala-async-dotty-cps-async" % "0.9.19" // allows cross compilation w/o changes in source code
5962

60-
val scalikeJdbc = "org.scalikejdbc" %% "scalikejdbc" % "3.5.0"
63+
val scalikeJdbc = "org.scalikejdbc" %% "scalikejdbc" % "4.1.0"
6164
val h2 = "com.h2database" % "h2" % "2.2.224"
6265

6366
val common = Seq(scalalogging)
@@ -74,7 +77,12 @@ val buildSettings = commonSmlBuildSettings ++ ossPublishSettings ++ Seq(
7477
ScmInfo(url("https://github.com/softwaremill/elasticmq"), "scm:git@github.com:softwaremill/elasticmq.git")
7578
),
7679
scalaVersion := resolvedScalaVersion,
77-
scalacOptions ++= Seq("-Xasync", "-target:jvm-1.8"),
80+
scalacOptions ++= {
81+
CrossVersion.partialVersion(scalaVersion.value) match {
82+
case Some((3, _)) => Seq("-Xtarget:8")
83+
case _ => Seq("-Xasync", "-target:jvm-1.8")
84+
}
85+
},
7886
libraryDependencies += scalaXml,
7987
dependencyOverrides := pekko100verrides,
8088
parallelExecution := false,
@@ -131,7 +139,10 @@ lazy val persistenceCore: Project = (project in file("persistence/persistence-co
131139
pekkoSlf4j,
132140
config,
133141
pekkoTestkit,
134-
scalaAsync
142+
CrossVersion.partialVersion(scalaVersion.value) match {
143+
case Some((3, _)) => scala3Async
144+
case _ => scala2Async
145+
}
135146
) ++ common
136147
)
137148
)
@@ -180,7 +191,10 @@ lazy val restSqs: Project = (project in file("rest/rest-sqs"))
180191
pekkoHttpSprayJson,
181192
pekkoTestkit,
182193
pekkoHttpTestkit,
183-
scalaAsync
194+
CrossVersion.partialVersion(scalaVersion.value) match {
195+
case Some((3, _)) => scala3Async
196+
case _ => scala2Async
197+
}
184198
) ++ common
185199
)
186200
)

core/src/main/scala/org/elasticmq/DeliveryReceipt.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ object DeliveryReceipt {
1313
private val Separator = "#"
1414

1515
def generate(id: MessageId) =
16-
new DeliveryReceipt(id + Separator + UUID.randomUUID().toString)
16+
new DeliveryReceipt(String.valueOf(id) + Separator + UUID.randomUUID().toString)
1717
}

core/src/main/scala/org/elasticmq/actor/queue/QueueActorMessageOps.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ trait QueueActorMessageOps
1919
this: QueueActorStorage =>
2020

2121
def nowProvider: NowProvider
22-
def context: org.apache.pekko.actor.ActorContext
2322

2423
timers.startTimerWithFixedDelay(s"Timer: ${queueData.name}", DeduplicationIdsCleanup, 1.second)
2524

core/src/main/scala/org/elasticmq/actor/queue/QueueActorQueueOps.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.elasticmq.actor.queue
22

33
import org.elasticmq.{FifoDeduplicationIdsHistory, QueueStatistics}
44
import org.elasticmq.actor.reply.ReplyAction
5+
import org.elasticmq.actor.reply.valueToReplyWith
56
import org.elasticmq.msg._
67
import org.elasticmq.util.Logging
78

core/src/main/scala/org/elasticmq/actor/reply/ReplyingActor.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ trait ReplyingActor extends Actor {
1717
private def doReceiveAndReply[T](msg: M[T]): Unit = {
1818
try {
1919
receiveAndReply(msg) match {
20-
case ReplyWith(t) => sender ! t
20+
case ReplyWith(t) => sender() ! t
2121
case DoNotReply() => // do nothing
2222
}
2323
} catch {
24-
case e: Exception => sender ! Failure(e)
24+
case e: Exception => sender() ! Failure(e)
2525
}
2626
}
2727

core/src/test/scala/org/elasticmq/actor/QueueActorMsgOpsTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ class QueueActorMsgOpsTest extends ActorTest with QueueManagerForEachTest with D
142142
val lookedUpReceipt = lookupAfterReceiving.flatMap(_.deliveryReceipt)
143143

144144
receivedReceipt.size should be > (0)
145-
lookedUpReceipt should be('defined)
145+
lookedUpReceipt should be(Symbol("defined"))
146146

147147
receivedReceipt.headOption should be(lookedUpReceipt)
148148
}

core/src/test/scala/org/elasticmq/actor/QueueManagerActorTest.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class QueueManagerActorTest extends ActorTest with QueueManagerForEachTest with
3131
lookupResult <- queueManagerActor ? LookupQueue("q2")
3232
} yield {
3333
// Then
34-
lookupResult should be('defined)
34+
lookupResult should be(Symbol("defined"))
3535
}
3636
}
3737

@@ -52,7 +52,7 @@ class QueueManagerActorTest extends ActorTest with QueueManagerForEachTest with
5252
r2 <- queueManagerActor ? LookupQueue(q2.name)
5353
} yield {
5454
r1 should be(None)
55-
r2 should be('defined)
55+
r2 should be(Symbol("defined"))
5656
}
5757
}
5858

@@ -66,7 +66,7 @@ class QueueManagerActorTest extends ActorTest with QueueManagerForEachTest with
6666
// When & then
6767
result <- queueManagerActor ? CreateQueue(q1)
6868
} yield {
69-
result should be('right)
69+
result should be(Symbol("right"))
7070
}
7171
}
7272

@@ -81,7 +81,7 @@ class QueueManagerActorTest extends ActorTest with QueueManagerForEachTest with
8181
// When & then
8282
result <- queueManagerActor ? CreateQueue(q2)
8383
} yield {
84-
result should be('left)
84+
result should be(Symbol("left"))
8585
}
8686
}
8787

core/src/test/scala/org/elasticmq/actor/test/ActorTest.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import org.scalatest.concurrent.ScalaFutures
77
import org.scalatest.BeforeAndAfterAll
88

99
import scala.concurrent.duration._
10+
import scala.concurrent.ExecutionContext
1011
import org.scalatest.funsuite.AsyncFunSuiteLike
1112
import org.scalatest.matchers.should.Matchers
1213

@@ -18,7 +19,7 @@ abstract class ActorTest
1819
with BeforeAndAfterAll {
1920
private val maxDuration = 1.minute
2021
implicit val timeout: Timeout = maxDuration
21-
implicit val ec = system.dispatcher
22+
implicit val ec: ExecutionContext = system.dispatcher
2223

2324
override protected def afterAll(): Unit = {
2425
system.terminate().futureValue

persistence/persistence-file/src/main/scala/org/elasticmq/persistence/file/QueuePersister.scala

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,22 @@ package org.elasticmq.persistence.file
22

33
import com.typesafe.config.ConfigRenderOptions
44
import org.elasticmq.{DeadLettersQueueData, QueueData}
5-
import pureconfig.generic.ProductHint
6-
import pureconfig.generic.auto._
7-
import pureconfig.{CamelCase, ConfigFieldMapping, ConfigWriter}
5+
import pureconfig.ConfigWriter
86

97
import java.io.PrintWriter
108

119
object QueuePersister {
1210

13-
private implicit val queueMetadataHint: ProductHint[QueueMetadata] =
14-
ProductHint[QueueMetadata](ConfigFieldMapping(CamelCase, CamelCase))
15-
private implicit val deadLettersHint: ProductHint[DeadLettersQueueData] =
16-
ProductHint[DeadLettersQueueData](ConfigFieldMapping(CamelCase, CamelCase))
11+
private implicit val deadLettersWriter: ConfigWriter[DeadLettersQueueData] =
12+
ConfigWriter.forProduct2[DeadLettersQueueData, String, Int]("name", "maxReceiveCount")(deadLetterQueueData =>
13+
(deadLetterQueueData.name, deadLetterQueueData.maxReceiveCount)
14+
)
15+
private implicit val queueMetadataWriter: ConfigWriter[QueueMetadata] =
16+
ConfigWriter.forProduct9[QueueMetadata, Long, Long, Long, Option[DeadLettersQueueData], Boolean, Boolean, String, String, Map[String,String]](
17+
"defaultVisibilityTimeout", "delay", "receiveMessageWait", "deadLettersQueue", "fifo", "contentBasedDeduplication", "copyTo", "moveTo", "tags"
18+
)(qm =>
19+
(qm.defaultVisibilityTimeout, qm.delay, qm.receiveMessageWait, qm.deadLettersQueue, qm.fifo, qm.contentBasedDeduplication, qm.copyTo, qm.moveTo, qm.tags)
20+
)
1721

1822
def saveToConfigFile(queues: List[QueueData], storagePath: String): Unit = {
1923
val queuesConfig: String = prepareQueuesConfig(queues)

0 commit comments

Comments
 (0)