Skip to content

Commit a271739

Browse files
authored
Provide util for jsonrpclib-smithy4s (#3)
* Provide util for jsonrpclib-smithy4s * fixed version of jsonrpclib based on neandertech/jsonrpclib#81 * Kasper generated the traits, thank you Kasper * publish from branch * jdk17 * jdk21
1 parent c346c25 commit a271739

File tree

6 files changed

+132
-32
lines changed

6 files changed

+132
-32
lines changed

.github/workflows/ci.yml

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
matrix:
3030
os: [ubuntu-22.04]
3131
scala: [3]
32-
java: [temurin@11]
32+
java: [temurin@21]
3333
runs-on: ${{ matrix.os }}
3434
timeout-minutes: 60
3535
steps:
@@ -41,47 +41,47 @@ jobs:
4141
- name: Setup sbt
4242
uses: sbt/setup-sbt@v1
4343

44-
- name: Setup Java (temurin@11)
45-
id: setup-java-temurin-11
46-
if: matrix.java == 'temurin@11'
44+
- name: Setup Java (temurin@21)
45+
id: setup-java-temurin-21
46+
if: matrix.java == 'temurin@21'
4747
uses: actions/setup-java@v4
4848
with:
4949
distribution: temurin
50-
java-version: 11
50+
java-version: 21
5151
cache: sbt
5252

5353
- name: sbt update
54-
if: matrix.java == 'temurin@11' && steps.setup-java-temurin-11.outputs.cache-hit == 'false'
54+
if: matrix.java == 'temurin@21' && steps.setup-java-temurin-21.outputs.cache-hit == 'false'
5555
run: sbt +update
5656

5757
- name: Check that workflows are up to date
5858
run: sbt githubWorkflowCheck
5959

6060
- name: Check headers and formatting
61-
if: matrix.java == 'temurin@11' && matrix.os == 'ubuntu-22.04'
61+
if: matrix.java == 'temurin@21' && matrix.os == 'ubuntu-22.04'
6262
run: sbt '++ ${{ matrix.scala }}' headerCheckAll scalafmtCheckAll 'project /' scalafmtSbtCheck
6363

6464
- name: Test
6565
run: sbt '++ ${{ matrix.scala }}' test
6666

6767
- name: Check binary compatibility
68-
if: matrix.java == 'temurin@11' && matrix.os == 'ubuntu-22.04'
68+
if: matrix.java == 'temurin@21' && matrix.os == 'ubuntu-22.04'
6969
run: sbt '++ ${{ matrix.scala }}' mimaReportBinaryIssues
7070

7171
- name: Generate API documentation
72-
if: matrix.java == 'temurin@11' && matrix.os == 'ubuntu-22.04'
72+
if: matrix.java == 'temurin@21' && matrix.os == 'ubuntu-22.04'
7373
run: sbt '++ ${{ matrix.scala }}' doc
7474

7575
- name: Make target directories
76-
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
76+
if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/jsonrpclib-smithy4s')
7777
run: mkdir -p sampleServer/target codegen/target transformation/target bsp4s/target project/target
7878

7979
- name: Compress target directories
80-
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
80+
if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/jsonrpclib-smithy4s')
8181
run: tar cf targets.tar sampleServer/target codegen/target transformation/target bsp4s/target project/target
8282

8383
- name: Upload target directories
84-
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
84+
if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/jsonrpclib-smithy4s')
8585
uses: actions/upload-artifact@v4
8686
with:
8787
name: target-${{ matrix.os }}-${{ matrix.java }}-${{ matrix.scala }}
@@ -90,11 +90,11 @@ jobs:
9090
publish:
9191
name: Publish Artifacts
9292
needs: [build]
93-
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
93+
if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/jsonrpclib-smithy4s')
9494
strategy:
9595
matrix:
9696
os: [ubuntu-22.04]
97-
java: [temurin@11]
97+
java: [temurin@21]
9898
runs-on: ${{ matrix.os }}
9999
steps:
100100
- name: Checkout current branch (full)
@@ -105,17 +105,17 @@ jobs:
105105
- name: Setup sbt
106106
uses: sbt/setup-sbt@v1
107107

108-
- name: Setup Java (temurin@11)
109-
id: setup-java-temurin-11
110-
if: matrix.java == 'temurin@11'
108+
- name: Setup Java (temurin@21)
109+
id: setup-java-temurin-21
110+
if: matrix.java == 'temurin@21'
111111
uses: actions/setup-java@v4
112112
with:
113113
distribution: temurin
114-
java-version: 11
114+
java-version: 21
115115
cache: sbt
116116

117117
- name: sbt update
118-
if: matrix.java == 'temurin@11' && steps.setup-java-temurin-11.outputs.cache-hit == 'false'
118+
if: matrix.java == 'temurin@21' && steps.setup-java-temurin-21.outputs.cache-hit == 'false'
119119
run: sbt +update
120120

121121
- name: Download target directories (3)
@@ -158,7 +158,7 @@ jobs:
158158
strategy:
159159
matrix:
160160
os: [ubuntu-22.04]
161-
java: [temurin@11]
161+
java: [temurin@21]
162162
runs-on: ${{ matrix.os }}
163163
steps:
164164
- name: Checkout current branch (full)
@@ -169,17 +169,17 @@ jobs:
169169
- name: Setup sbt
170170
uses: sbt/setup-sbt@v1
171171

172-
- name: Setup Java (temurin@11)
173-
id: setup-java-temurin-11
174-
if: matrix.java == 'temurin@11'
172+
- name: Setup Java (temurin@21)
173+
id: setup-java-temurin-21
174+
if: matrix.java == 'temurin@21'
175175
uses: actions/setup-java@v4
176176
with:
177177
distribution: temurin
178-
java-version: 11
178+
java-version: 21
179179
cache: sbt
180180

181181
- name: sbt update
182-
if: matrix.java == 'temurin@11' && steps.setup-java-temurin-11.outputs.cache-hit == 'false'
182+
if: matrix.java == 'temurin@21' && steps.setup-java-temurin-21.outputs.cache-hit == 'false'
183183
run: sbt +update
184184

185185
- name: Submit Dependencies

bsp4s/src/main/scala/smithy4sbsp/bsp4s/BSPBuilder.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@
1616

1717
package smithy4sbsp.bsp4s
1818

19-
import bsp.traits.JsonNotification
20-
21-
import bsp.traits.JsonRequest
2219
import jsonrpclib.Codec
2320
import jsonrpclib.Endpoint
2421
import smithy4s.Service
2522
import cats.syntax.all.*
2623
import jsonrpclib.Monadic
24+
import jsonrpclib.JsonRequest
25+
import jsonrpclib.JsonNotification
2726

2827
final case class BSPBuilder[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]] private (
2928
private val service: Service.Aux[Alg, Op],

bsp4s/src/main/scala/smithy4sbsp/bsp4s/BSPCodecs.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ import smithy4s.schema.Schema
2929
import util.chaining.*
3030
import smithy4sbsp.meta.RpcPayload
3131
import smithy4s.schema.Schema.StructSchema
32+
import smithy4s.Service
33+
import jsonrpclib.smithy4sinterop.ClientStub
34+
import jsonrpclib.fs2.FS2Channel
35+
import cats.effect.kernel.Async
36+
import smithy4s.Endpoint
37+
import smithy4s.schema.OperationSchema
3238

3339
object BSPCodecs {
3440

@@ -53,6 +59,27 @@ object BSPCodecs {
5359
def encode(a: A): Payload = Payload.Data(encoder.encode(a).toArrayUnsafe)
5460
}
5561

62+
def clientStub[Alg[_[_, _, _, _, _]], F[_]: Async](service: Service[Alg], chan: FS2Channel[F])
63+
: F[service.Impl[F]] = ClientStub(bspServiceTransformations(service), chan)
64+
65+
// todo: probably should be private
66+
def bspServiceTransformations[Alg[_[_, _, _, _, _]]]: Service[Alg] => Service[Alg] =
67+
_.toBuilder
68+
.mapEndpointEach(
69+
Endpoint.mapSchema(
70+
OperationSchema
71+
.mapInputK(
72+
Schema.transformTransitivelyK(bspTransformations)
73+
)
74+
.andThen(
75+
OperationSchema.mapOutputK(
76+
Schema.transformTransitivelyK(bspTransformations)
77+
)
78+
)
79+
)
80+
)
81+
.build
82+
5683
private def bspTransformations: Schema ~> Schema =
5784
new (Schema ~> Schema) {
5885
def apply[A0](fa: Schema[A0]): Schema[A0] =

build.sbt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ ThisBuild / organization := "org.polyvariant.smithy4s-bsp"
33
ThisBuild / organizationName := "Polyvariant"
44
ThisBuild / startYear := Some(2025)
55
ThisBuild / licenses := Seq(License.Apache2)
6-
ThisBuild / developers := List( /* tlGitHubDev() */ )
6+
ThisBuild / developers := List(tlGitHubDev("kubukoz", "Jakub Kozłowski"))
77
ThisBuild / sonatypeCredentialHost := xerial.sbt.Sonatype.sonatype01
88

9+
ThisBuild / githubWorkflowPublishTargetBranches := Seq(
10+
RefPredicate.Equals(Ref.Branch("main")),
11+
RefPredicate.Equals(Ref.Branch("jsonrpclib-smithy4s")),
12+
)
913
ThisBuild / scalaVersion := "3.3.5"
10-
ThisBuild / tlJdkRelease := Some(11)
14+
ThisBuild / tlJdkRelease := Some(21)
1115
ThisBuild / tlFatalWarnings := false
16+
ThisBuild / resolvers ++= Resolver.sonatypeOssRepos("snapshots")
1217

1318
val commonSettings = Seq(
1419
scalacOptions -= "-Ykind-projector:underscores",
@@ -25,6 +30,7 @@ lazy val transformation = project
2530
libraryDependencies ++= Seq(
2631
"software.amazon.smithy" % "smithy-build" % "1.57.1",
2732
"ch.epfl.scala" % "spec-traits" % "2.2.0-M2",
33+
"tech.neander" % "jsonrpclib-smithy" % "0.0.8+20-8d37b4ca-SNAPSHOT",
2834
"com.disneystreaming.alloy" % "alloy-core" % "0.3.19",
2935
),
3036
publish / skip := true,
@@ -36,13 +42,15 @@ lazy val codegen = project
3642
libraryDependencies ++= Seq(
3743
"ch.epfl.scala" % "spec" % "2.2.0-M2" % Smithy4s,
3844
"ch.epfl.scala" % "spec-traits" % "2.2.0-M2" % Smithy4s,
45+
"tech.neander" % "jsonrpclib-smithy" % "0.0.8+20-8d37b4ca-SNAPSHOT" % Smithy4s,
3946
"com.disneystreaming.smithy4s" %%% "smithy4s-core" % smithy4sVersion.value,
4047
),
4148
Compile / smithy4sModelTransformers := List(
4249
"untagged-unions",
4350
"set-shapes",
4451
"open-enums",
4552
"transform-build-target-data",
53+
"transform-jsonrpclib-traits",
4654
"rename-scala-namespace",
4755
),
4856
Compile / smithy4sAllDependenciesAsJars += (transformation / Compile / packageBin).value,
@@ -54,7 +62,7 @@ lazy val bsp4s = project
5462
commonSettings,
5563
libraryDependencies ++= Seq(
5664
"org.typelevel" %% "cats-effect-kernel" % "3.6.1",
57-
"tech.neander" %%% "jsonrpclib-core" % "0.0.7",
65+
"tech.neander" %%% "jsonrpclib-smithy4s" % "0.0.8+20-8d37b4ca-SNAPSHOT",
5866
"com.disneystreaming.smithy4s" %%% "smithy4s-json" % smithy4sVersion.value,
5967
"com.disneystreaming" %%% "weaver-cats" % "0.8.4" % Test,
6068
),
@@ -65,7 +73,7 @@ lazy val sampleServer = project
6573
.settings(
6674
commonSettings,
6775
libraryDependencies ++= Seq(
68-
"tech.neander" %%% "jsonrpclib-fs2" % "0.0.7",
76+
"tech.neander" %%% "jsonrpclib-fs2" % "0.0.8+20-8d37b4ca-SNAPSHOT",
6977
"co.fs2" %%% "fs2-io" % "3.12.0",
7078
"com.disneystreaming.smithy4s" %%% "smithy4s-json" % smithy4sVersion.value,
7179
"com.disneystreaming" %%% "weaver-cats" % "0.8.4" % Test,

transformation/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ UntaggedUnions
22
SetShapes
33
OpenEnums
44
TransformBuildTargetData
5+
TransformJsonRpcTraits
56
RenameScalaNamespace
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2025 Polyvariant
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import software.amazon.smithy.build.ProjectionTransformer
18+
import software.amazon.smithy.build.TransformContext
19+
import software.amazon.smithy.model.Model
20+
import software.amazon.smithy.model.transform.ModelTransformer
21+
import bsp.traits.JsonNotificationTrait
22+
import bsp.traits.JsonRequestTrait
23+
import bsp.traits.JsonRPCTrait
24+
25+
class TransformJsonRpcTraits extends ProjectionTransformer {
26+
def getName(): String = "transform-jsonrpclib-traits"
27+
28+
def transform(context: TransformContext): Model = ModelTransformer
29+
.create()
30+
.mapShapes(
31+
context.getModel(),
32+
s =>
33+
s match {
34+
case s if s.hasTrait(JsonRPCTrait.ID) =>
35+
val builder = s.asServiceShape.get.toBuilder()
36+
builder.removeTrait(JsonRPCTrait.ID)
37+
builder.addTrait(jsonrpclib.JsonRPCTrait.builder().build())
38+
builder.build()
39+
40+
case s if s.hasTrait(JsonNotificationTrait.ID) =>
41+
val builder = s.asOperationShape.get.toBuilder()
42+
builder.removeTrait(JsonNotificationTrait.ID)
43+
builder.addTrait(
44+
new jsonrpclib.JsonNotificationTrait.Provider().createTrait(
45+
jsonrpclib.JsonNotificationTrait.ID,
46+
s.getAllTraits().get(JsonNotificationTrait.ID).toNode(),
47+
)
48+
)
49+
builder.build()
50+
51+
case s if s.hasTrait(JsonRequestTrait.ID) =>
52+
val builder = s.asOperationShape.get.toBuilder()
53+
builder.removeTrait(JsonRequestTrait.ID)
54+
builder.addTrait(
55+
new jsonrpclib.JsonRequestTrait.Provider().createTrait(
56+
jsonrpclib.JsonRequestTrait.ID,
57+
s.getAllTraits().get(JsonRequestTrait.ID).toNode(),
58+
)
59+
)
60+
builder.build()
61+
case s => s
62+
},
63+
)
64+
65+
}

0 commit comments

Comments
 (0)