Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit c666413

Browse files
authored
Merge pull request #431 from polyvariant/scala3
2 parents 06c8a6f + 20fe87f commit c666413

22 files changed

+311
-191
lines changed

.github/workflows/ci.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
strategy:
2323
matrix:
2424
os: [ubuntu-latest]
25-
scala: [2.13.6]
25+
scala: [3.1.1]
2626
2727
runs-on: ${{ matrix.os }}
2828
steps:
@@ -78,7 +78,7 @@ jobs:
7878
strategy:
7979
matrix:
8080
os: [ubuntu-latest]
81-
scala: [2.13.6]
81+
scala: [3.1.1]
8282
8383
runs-on: ${{ matrix.os }}
8484
steps:
@@ -104,12 +104,12 @@ jobs:
104104
~/Library/Caches/Coursier/v1
105105
key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
106106

107-
- name: Download target directories (2.13.6)
107+
- name: Download target directories (3.1.1)
108108
uses: actions/download-artifact@v2
109109
with:
110-
name: target-${{ matrix.os }}-2.13.6-${{ matrix.java }}
110+
name: target-${{ matrix.os }}-3.1.1-${{ matrix.java }}
111111

112-
- name: Inflate target directories (2.13.6)
112+
- name: Inflate target directories (3.1.1)
113113
run: |
114114
tar xf targets.tar
115115
rm targets.tar

.scalafmt.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
runner.dialect=scala213
1+
runner.dialect=scala3
22

33
version = "3.5.3"
44
maxColumn = 140

build.sbt

+14-20
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import com.typesafe.sbt.packager.docker.Cmd
22

33
import com.typesafe.sbt.packager.docker.ExecCmd
44

5+
Global / onChangedBuildSource := ReloadOnSourceChanges
6+
57
inThisBuild(
68
List(
79
organization := "io.pg",
@@ -22,9 +24,9 @@ inThisBuild(
2224

2325
val GraalVM11 = "[email protected]"
2426

25-
val Scala213 = "2.13.6"
26-
ThisBuild / scalaVersion := Scala213
27-
ThisBuild / crossScalaVersions := Seq(Scala213)
27+
val Scala3 = "3.1.1"
28+
ThisBuild / scalaVersion := Scala3
29+
ThisBuild / crossScalaVersions := Seq(Scala3)
2830
ThisBuild / githubWorkflowJavaVersions := Seq(GraalVM11)
2931

3032
ThisBuild / githubWorkflowPublishTargetBranches := Seq(
@@ -67,23 +69,18 @@ def crossPlugin(x: sbt.librarymanagement.ModuleID) =
6769
compilerPlugin(x.cross(CrossVersion.full))
6870

6971
val compilerPlugins = List(
70-
crossPlugin("org.typelevel" % "kind-projector" % "0.13.2"),
71-
crossPlugin("com.github.cb372" % "scala-typed-holes" % "0.1.11"),
72-
crossPlugin("org.polyvariant" % "better-tostring" % "0.3.15"),
73-
compilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1")
72+
crossPlugin("org.polyvariant" % "better-tostring" % "0.3.15")
7473
)
7574

7675
val commonSettings = List(
7776
scalacOptions --= List("-Xfatal-warnings"),
78-
scalacOptions += "-Ymacro-annotations",
7977
libraryDependencies ++= List(
8078
"org.typelevel" %% "cats-core" % "2.7.0",
8179
"org.typelevel" %% "cats-effect" % "3.3.12",
82-
"org.typelevel" %% "cats-tagless-macros" % "0.14.0",
8380
"co.fs2" %% "fs2-core" % "3.2.7",
8481
"com.github.valskalla" %% "odin-core" % "0.13.0",
85-
"io.circe" %% "circe-core" % "0.14.1",
86-
"dev.optics" %% "monocle-macro" % "3.1.0",
82+
"io.circe" %% "circe-core" % "0.14.2",
83+
"dev.optics" %% "monocle-core" % "3.1.0",
8784
"com.disneystreaming" %% "weaver-cats" % "0.7.11" % Test,
8885
"com.disneystreaming" %% "weaver-scalacheck" % "0.7.11" % Test
8986
) ++ compilerPlugins,
@@ -97,9 +94,8 @@ lazy val gitlab = project
9794
libraryDependencies ++= List(
9895
"is.cir" %% "ciris" % "2.3.2",
9996
"com.kubukoz" %% "caliban-gitlab" % "0.1.0",
100-
"io.circe" %% "circe-generic-extras" % "0.14.1",
101-
"io.circe" %% "circe-parser" % "0.14.1" % Test,
102-
"io.circe" %% "circe-literal" % "0.14.1" % Test,
97+
"io.circe" %% "circe-parser" % "0.14.2" % Test,
98+
"io.circe" %% "circe-literal" % "0.14.2" % Test,
10399
"com.softwaremill.sttp.tapir" %% "tapir-core" % "0.18.0-M17",
104100
"com.softwaremill.sttp.tapir" %% "tapir-json-circe" % "0.18.0-M17",
105101
"com.softwaremill.sttp.tapir" %% "tapir-sttp-client" % "0.18.0-M17"
@@ -109,18 +105,17 @@ lazy val gitlab = project
109105

110106
lazy val bootstrap = project
111107
.settings(
112-
scalaVersion := "3.0.0",
108+
scalaVersion := Scala3,
113109
libraryDependencies ++= List(
114110
"org.typelevel" %% "cats-core" % "2.7.0",
115111
"org.typelevel" %% "cats-effect" % "3.3.12",
116112
"com.kubukoz" %% "caliban-gitlab" % "0.1.0",
117113
"com.softwaremill.sttp.client3" %% "core" % "3.3.15",
118114
"com.softwaremill.sttp.client3" %% "circe" % "3.3.15",
119-
"io.circe" %% "circe-core" % "0.14.1",
115+
"io.circe" %% "circe-core" % "0.14.2",
120116
crossPlugin("org.polyvariant" % "better-tostring" % "0.3.15")
121117
),
122118
publish / skip := true,
123-
// Compile / mainClass := Some("org.polyvariant.Main"),
124119
githubWorkflowArtifactUpload := false,
125120
nativeImageVersion := "22.1.0",
126121
nativeImageOptions ++= Seq(
@@ -195,12 +190,11 @@ lazy val pitgull =
195190
"org.http4s" %% "http4s-blaze-server" % "0.23.11",
196191
"org.http4s" %% "http4s-blaze-client" % "0.23.11",
197192
"is.cir" %% "ciris" % "2.3.2",
198-
"io.circe" %% "circe-generic-extras" % "0.14.0",
199-
"io.scalaland" %% "chimney" % "0.6.1",
200193
"io.chrisdavenport" %% "cats-time" % "0.4.0",
201194
"com.github.valskalla" %% "odin-core" % "0.13.0",
202195
"com.github.valskalla" %% "odin-slf4j" % "0.13.0",
203-
"io.github.vigoo" %% "prox-fs2-3" % "0.7.7"
196+
"io.github.vigoo" %% "prox-fs2-3" % "0.7.7",
197+
"io.circe" %% "circe-literal" % "0.14.2" % Test
204198
)
205199
)
206200
.dependsOn(core, gitlab)

core/src/main/scala/io/pg/Prelude.scala

-9
This file was deleted.

core/src/main/scala/io/pg/messaging/messaging.scala

+13-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package io.pg.messaging
22

33
import cats.effect.std.Queue
44
import scala.reflect.ClassTag
5-
import cats.tagless.autoInvariant
65
import cats.syntax.all._
76
import cats.ApplicativeError
87
import io.odin.Logger
98
import cats.Functor
9+
import cats.Invariant
10+
import cats.ApplicativeThrow
1011

1112
trait Publisher[F[_], -A] {
1213
def publish(a: A): F[Unit]
@@ -16,7 +17,7 @@ final case class Processor[F[_], -A](process: fs2.Pipe[F, A, Unit])
1617

1718
object Processor {
1819

19-
def simple[F[_]: ApplicativeError[*[_], Throwable]: Logger, A](
20+
def simple[F[_]: ApplicativeThrow: Logger, A](
2021
f: A => F[Unit]
2122
): Processor[F, A] =
2223
Processor[F, A] {
@@ -35,13 +36,21 @@ object Processor {
3536

3637
}
3738

38-
@autoInvariant
39-
trait Channel[F[_], A] extends Publisher[F, A] { self =>
39+
trait Channel[F[_], A] extends Publisher[F, A] {
4040
def consume: fs2.Stream[F, A]
4141
}
4242

4343
object Channel {
4444

45+
given [F[_]]: Invariant[Channel[F, *]] with {
46+
47+
def imap[A, B](chan: Channel[F, A])(f: A => B)(g: B => A): Channel[F, B] = new {
48+
def consume: fs2.Stream[F, B] = chan.consume.map(f)
49+
def publish(b: B): F[Unit] = chan.publish(g(b))
50+
}
51+
52+
}
53+
4554
def fromQueue[F[_]: Functor, A](q: Queue[F, A]): Channel[F, A] =
4655
new Channel[F, A] {
4756
def publish(a: A): F[Unit] = q.offer(a)

gitlab/src/main/scala/io/pg/gitlab/Gitlab.scala

+13-15
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import caliban.client.SelectionBuilder
88
import cats.MonadError
99
import cats.kernel.Eq
1010
import cats.syntax.all._
11-
import cats.tagless.finalAlg
1211
import ciris.Secret
1312
import io.odin.Logger
1413
import io.pg.gitlab.Gitlab.MergeRequestInfo
@@ -30,14 +29,12 @@ import sttp.tapir.generic.auto._
3029
import sttp.tapir.json.circe._
3130
import fs2.Stream
3231
import io.circe.{Codec => CirceCodec}
33-
import io.circe.generic.extras.semiauto._
34-
import io.circe.generic.extras.Configuration
3532
import io.pg.gitlab.GitlabEndpoints.transport.MergeRequestApprovals
36-
import monocle.macros.Lenses
33+
import monocle.syntax.all._
3734
import cats.Show
3835
import io.pg.TextUtils
36+
import cats.MonadThrow
3937

40-
@finalAlg
4138
trait Gitlab[F[_]] {
4239
def mergeRequests(projectId: Long): F[List[MergeRequestInfo]]
4340
def acceptMergeRequest(projectId: Long, mergeRequestIid: Long): F[Unit]
@@ -47,10 +44,11 @@ trait Gitlab[F[_]] {
4744

4845
object Gitlab {
4946

47+
def apply[F[_]](using F: Gitlab[F]): Gitlab[F] = F
48+
5049
// VCS-specific MR information
5150
// Not specific to the method of fetching (no graphql model references etc.)
5251
// Fields only required according to reason (e.g. must have a numeric ID - we might loosen this later)
53-
@Lenses
5452
final case class MergeRequestInfo(
5553
projectId: Long,
5654
mergeRequestIid: Long,
@@ -62,20 +60,19 @@ object Gitlab {
6260
)
6361

6462
object MergeRequestInfo {
65-
sealed trait Status extends Product with Serializable
6663

67-
object Status {
68-
case object Success extends Status
69-
final case class Other(value: String) extends Status
64+
enum Status {
65+
case Success
66+
case Other(value: String)
7067

7168
implicit val eq: Eq[Status] = Eq.fromUniversalEquals
7269
}
7370

7471
implicit val showTrimmed: Show[MergeRequestInfo] =
75-
MergeRequestInfo.description.modify(_.map(TextUtils.inline).map(TextUtils.trim(maxChars = 30))).apply(_).toString
72+
_.focus(_.description).modify(_.map(TextUtils.inline).map(TextUtils.trim(maxChars = 30))).toString
7673
}
7774

78-
def sttpInstance[F[_]: Logger: MonadError[*[_], Throwable]](
75+
def sttpInstance[F[_]: Logger: MonadThrow](
7976
baseUri: Uri,
8077
accessToken: Secret[String]
8178
)(
@@ -278,20 +275,21 @@ object GitlabEndpoints {
278275
.in(query[Int]("approvals_required"))
279276

280277
object transport {
281-
implicit val config: Configuration = Configuration.default.withSnakeCaseMemberNames
282278

283279
final case class ApprovalRule(id: Long, name: String, ruleType: String) {
284280
val isMutable: Boolean = ruleType != "code_owner"
285281
}
286282

287283
object ApprovalRule {
288-
implicit val codec: CirceCodec[ApprovalRule] = deriveConfiguredCodec
284+
// todo: use configured codec when https://github.com/circe/circe/pull/1800 is available
285+
given CirceCodec[ApprovalRule] = CirceCodec.forProduct3("id", "name", "rule_type")(apply)(r => (r.id, r.name, r.ruleType))
289286
}
290287

291288
final case class MergeRequestApprovals(approvalsRequired: Int)
292289

293290
object MergeRequestApprovals {
294-
implicit val codec: CirceCodec[MergeRequestApprovals] = deriveConfiguredCodec
291+
// todo: use configured codec when https://github.com/circe/circe/pull/1800 is available
292+
given CirceCodec[MergeRequestApprovals] = CirceCodec.forProduct1("approvals_required")(apply)(_.approvalsRequired)
295293
}
296294

297295
}

gitlab/src/main/scala/io/pg/gitlab/webhook/webhook.scala

+6-16
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,17 @@
11
package io.pg.gitlab.webhook
22

3-
import io.circe.generic.extras._
3+
import io.circe.Codec
44

5-
private object CirceConfiguration {
6-
7-
implicit val config: Configuration =
8-
Configuration
9-
.default
10-
.withSnakeCaseMemberNames
11-
.withSnakeCaseConstructorNames
12-
.withDiscriminator("object_kind")
5+
final case class WebhookEvent(project: Project, objectKind: String /* for logs */ )
136

7+
object WebhookEvent {
8+
// todo: use configured codec when https://github.com/circe/circe/pull/1800 is available
9+
given Codec[WebhookEvent] = Codec.forProduct2("project", "object_kind")(apply)(we => (we.project, we.objectKind))
1410
}
1511

16-
import CirceConfiguration._
17-
18-
@ConfiguredJsonCodec
19-
final case class WebhookEvent(project: Project, objectKind: String /* for logs */ )
20-
21-
@ConfiguredJsonCodec
2212
final case class Project(
2313
id: Long
24-
)
14+
) derives Codec.AsObject
2515

2616
object Project {
2717
val demo = Project(20190338)

src/main/scala/io/pg/Application.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ object Application {
3636
def resource[F[_]: Logger: Async](
3737
config: AppConfig
3838
): Resource[F, Application[F]] = {
39-
implicit val projectConfigReader = ProjectConfigReader.test[F]
39+
given ProjectConfigReader[F] = ProjectConfigReader.test[F]
4040

4141
Queue
4242
.bounded[F, Event](config.queues.maxSize)
4343
.map(Channel.fromQueue(_))
4444
.toResource
4545
.flatMap { eventChannel =>
4646
implicit val webhookChannel: Channel[F, WebhookEvent] =
47-
eventChannel.only[Event.Webhook].imap(_.value)(Event.Webhook)
47+
eventChannel.only[Event.Webhook].imap(_.value)(Event.Webhook.apply)
4848

4949
BlazeClientBuilder[F]
5050
.resource

src/main/scala/io/pg/Main.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@ object Main extends IOApp {
7878

7979
def serve[F[_]: Async](fToIO: F ~> IO)(config: AppConfig) =
8080
for {
81-
implicit0(logger: Logger[F]) <- mkLogger[F](fToIO)
82-
_ <- logStarting(config.meta).toResource
83-
resources <- Application.resource[F](config)
84-
_ <- mkServer[F](config, resources.routes)
85-
_ <- resources.background.parTraverse_(_.run).background
86-
_ <- logStarted(config.meta).toResource
81+
given Logger[F] <- mkLogger[F](fToIO)
82+
_ <- logStarting(config.meta).toResource
83+
resources <- Application.resource[F](config)
84+
_ <- mkServer[F](config, resources.routes)
85+
_ <- resources.background.parTraverse_(_.run).background
86+
_ <- logStarted(config.meta).toResource
8787
} yield ()
8888

8989
def run(args: List[String]): IO[ExitCode] =

src/main/scala/io/pg/MergeRequests.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import cats.Show
66
import cats.data.EitherNel
77
import cats.data.NonEmptyList
88
import cats.implicits._
9-
import cats.tagless.finalAlg
109
import fs2.Pipe
1110
import io.odin.Logger
1211
import io.pg.MergeRequestState
@@ -16,12 +15,13 @@ import io.pg.StateResolver
1615
import io.pg.config.ProjectConfigReader
1716
import io.pg.gitlab.webhook.Project
1817

19-
@finalAlg
2018
trait MergeRequests[F[_]] {
2119
def build(project: Project): F[List[MergeRequestState]]
2220
}
2321

2422
object MergeRequests {
23+
def apply[F[_]](using F: MergeRequests[F]): MergeRequests[F] = F
24+
2525
import scala.util.chaining._
2626

2727
def instance[F[_]: ProjectConfigReader: StateResolver: Monad: Logger](

src/main/scala/io/pg/actions.scala

+4-6
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ object ProjectActions {
176176
matchers
177177
.traverse(_.matches(input).swap)
178178
.swap
179-
.leftMap(Mismatch.ManyFailed)
179+
.leftMap(Mismatch.ManyFailed.apply)
180180
.toEitherNel
181181

182182
def not[A](matcher: MatcherFunction[A]): MatcherFunction[A] = input =>
@@ -211,9 +211,7 @@ object ProjectActions {
211211

212212
}
213213

214-
sealed trait ProjectAction extends Product with Serializable
215-
216-
object ProjectAction {
217-
final case class Merge(projectId: Long, mergeRequestIid: Long) extends ProjectAction
218-
final case class Rebase(projectId: Long, mergeRequestIid: Long) extends ProjectAction
214+
enum ProjectAction {
215+
case Merge(projectId: Long, mergeRequestIid: Long)
216+
case Rebase(projectId: Long, mergeRequestIid: Long)
219217
}

0 commit comments

Comments
 (0)