diff --git a/README.md b/README.md index 726098d..cf163e8 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ - [Configuring Scala Jackson and the addon-on "Enum" module for JSON support](#configuring-scala-jackson-and-the-addon-on-enum-module-for-json-support) - [Scala DSL for rest-assured (similar to Kotlin DSL)](#scala-dsl-for-rest-assured-similar-to-kotlin-dsl) - [Functional HTTP routes (Vert.x handlers)](#functional-http-routes-vertx-handlers) +- [Quarkus - Scala3 - ZIO](#quarkus---scala3---zio) ## Introduction @@ -462,3 +463,61 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! + +# Quarkus - Scala3 - ZIO +Add these dependencies to your `pom.xml` (respectively gradle): + +```xml + + io.quarkiverse.scala + quarkus-scala3-zio + 999-SNAPSHOT + + + io.quarkiverse.scala + quarkus-scala3-zio-deployment + 999-SNAPSHOT + +``` + +Now you're able to use a `ZIO[Any, E <: Throwable, A]` in your REST-Resources, e.g. + +```scala + final case class AsyncGreetingResponse(message: String, ip: String, time: Long) + + @GET + @Path("/greet/async") + @Produces(Array(APPLICATION_JSON)) + def asyncGreeting(): Task[AsyncGreetingResponse] = + val numsAmount = 10 + Log.debug(s"Generating $numsAmount numbers asynchronously...") + val startTime = System.currentTimeMillis() + // Get the IP address asynchronously + val IPFuture = ZIO.fromFuture(_ => getOwnIP().map(_.body).recover: + case e: Exception => + Log.error("Failed to get the IP address.") + Left("Failed to get IP")) + + val futureSum = ZIO.foreachPar((1 to numsAmount)){i => generateNum()}.map(_.sum) + for + sumF <- futureSum.fork + ipF <- IPFuture.map(_.merge).fork + result <- sumF.join zip ipF.join + (sum, ip) = result + yield + val endTime = System.currentTimeMillis() - startTime + Log.debug(s"My IP is: $ip") + Log.debug(s"Generated $numsAmount numbers asynchronously in ${endTime}ms") + + AsyncGreetingResponse( + s"The sum of the $numsAmount generated numbers is $sum. Was generated asynchronously in ${endTime}ms.\nYour IP is: $ip.", + ip, + endTime) + + end asyncGreeting + +``` + +Please note that we currently don't support anything in the Environment `R`, as we don't have a way +to transfer this information from Java to Scala. Also, your error type needs to be either Nothing +or a (subtype of) Throwable. diff --git a/pom.xml b/pom.xml index b80da21..69c1197 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.quarkiverse quarkiverse-parent - 15 + 16 io.quarkiverse.scala quarkus-scala3-parent @@ -14,6 +14,7 @@ deployment runtime + zio :git:git@github.com:quarkiverse/quarkus-scala3.git diff --git a/zio/TODO.md b/zio/TODO.md new file mode 100644 index 0000000..e02842a --- /dev/null +++ b/zio/TODO.md @@ -0,0 +1,10 @@ +# ZIO TODOs / IDEAs + +- ZIO-Config: Create implementation of ZIO ConfigProvider that is backed by the microprofile Config and + inject that into the environment / make it usable with ZIO.Config(..) [See ZIO-Configuration](https://zio.dev/reference/configuration/) +- ZIO-Logging: Bridge ZIO-Logging to Quarkus-Logger? +- Fill the environment with commonly required dependencies. +- Fill the environment with dependencies specified in the `R` type (we need to figure out how to parse that, as we loose type info in Java) +- Allow using `ZStream` where `Multi` is allowed atm (e.g. Kafka, SSE, etc.) +- Register the ZIO Runtime using a Provider, so it could be injected. +- ... diff --git a/zio/deployment/pom.xml b/zio/deployment/pom.xml new file mode 100644 index 0000000..248a68d --- /dev/null +++ b/zio/deployment/pom.xml @@ -0,0 +1,78 @@ + + + 4.0.0 + + + io.quarkiverse.scala + quarkus-scala3-zio-parent + 999-SNAPSHOT + + quarkus-scala3-zio-deployment + Quarkus Scala3 Zio - Deployment + + + + + io.quarkus + quarkus-arc-deployment + + + io.quarkiverse.scala + quarkus-scala3-zio + ${project.version} + + + io.quarkus + quarkus-junit5-internal + test + + + + io.quarkus + quarkus-rest-spi-deployment + + + io.quarkus.resteasy.reactive + resteasy-reactive-processor + + + io.quarkus + quarkus-rest-server-spi-deployment + + + + org.scala-lang + scala3-library_3 + compile + + + + dev.zio + zio_3 + + + + + + src/main/scala + src/test/scala + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + net.alchim31.maven + scala-maven-plugin + + + + diff --git a/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOJavaProcessor.java b/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOJavaProcessor.java new file mode 100644 index 0000000..2f7676b --- /dev/null +++ b/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOJavaProcessor.java @@ -0,0 +1,18 @@ +package io.quarkiverse.scala.scala3.zio.deployment; + +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.resteasy.reactive.server.spi.MethodScannerBuildItem; + +public class Scala3ZIOJavaProcessor { + + @BuildStep + public FeatureBuildItem feature() { + return new FeatureBuildItem("scala3-zio"); + } + + @BuildStep + public MethodScannerBuildItem registerZIORestReturnTypes() { + return new MethodScannerBuildItem(new Scala3ZIOReturnTypeMethodScanner()); + } +} diff --git a/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOResponseHandler.scala b/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOResponseHandler.scala new file mode 100644 index 0000000..cb7c170 --- /dev/null +++ b/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOResponseHandler.scala @@ -0,0 +1,44 @@ +package io.quarkiverse.scala.scala3.zio.deployment + +import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext +import org.jboss.resteasy.reactive.server.spi.ServerRestHandler +import zio.ZIO + +import scala.jdk.CollectionConverters.* + +class Scala3ZIOResponseHandler() extends ServerRestHandler { + + override def handle(requestContext: ResteasyReactiveRequestContext): Unit = { + val result = requestContext.getResult + + /* + TODO if we're able to read the environment from the effect, we might be able to hook into + Quarkus dependency injection mechanism to fill it here. For now, we can only assume its any. + */ + type R = Any + + /* fixing the error type to Throwable. We can be sure its this type, as we've checked + it before in io.quarkiverse.scala.scala3.zio.deployment.Scala3ZIOReturnTypeMethodScanner.scan + There it can only be Nothing, or Throwable or subtypes of Throwable, so either way, we're + safe to assume it's Throwable here. + */ + type E = Throwable + + /* We assume any as return type, as quarkus also accepts any object as return type. + */ + type A = Any + + requestContext.suspend() + val r = result.asInstanceOf[ZIO[R, E, A]] + + val r1 = r.fold(e => { + requestContext.handleException(e) + requestContext.resume() + }, a => { + requestContext.setResult(a) + requestContext.resume() + }) + + zio.Unsafe.unsafe(u => zio.Runtime.default.unsafe.runToFuture(r1)(zio.Trace.empty, u)) + } +} diff --git a/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOReturnTypeMethodScanner.scala b/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOReturnTypeMethodScanner.scala new file mode 100644 index 0000000..f0718fe --- /dev/null +++ b/zio/deployment/src/main/scala/io/quarkiverse/scala/scala3/zio/deployment/Scala3ZIOReturnTypeMethodScanner.scala @@ -0,0 +1,62 @@ +package io.quarkiverse.scala.scala3.zio.deployment + +import org.jboss.jandex.ClassInfo +import org.jboss.jandex.DotName +import org.jboss.jandex.MethodInfo +import org.jboss.jandex.Type +import org.jboss.resteasy.reactive.server.model.FixedHandlerChainCustomizer +import org.jboss.resteasy.reactive.server.model.HandlerChainCustomizer +import org.jboss.resteasy.reactive.server.processor.scanning.MethodScanner + +import java.util +import java.util.List as JList +import java.util.Collections as JCollections + +class Scala3ZIOReturnTypeMethodScanner extends MethodScanner { + private val ZIO = DotName.createSimple("zio.ZIO") + private val nothing$ = DotName.createSimple("scala.Nothing$") + private val throwable = DotName.createSimple("java.lang.Throwable") + + + override def scan(method: MethodInfo, + actualEndpointClass: ClassInfo, + methodContext: util.Map[String, AnyRef] + ): JList[HandlerChainCustomizer] = { + if(isMethodSignatureAsync(method)) { + ensuringFailureTypeIsNothingOrAThrowable(method) + JCollections.singletonList( + new FixedHandlerChainCustomizer( + new Scala3ZIOResponseHandler(), + HandlerChainCustomizer.Phase.AFTER_METHOD_INVOKE + ) + ) + } else { + JCollections.emptyList() + } + } + + private def ensuringFailureTypeIsNothingOrAThrowable(info: MethodInfo): Unit = { + import scala.jdk.CollectionConverters._ + val returnType = info.returnType() + val typeArguments: JList[Type] = returnType.asParameterizedType().arguments() + if (typeArguments.size() != 3) { + throw new RuntimeException("ZIO must have three type arguments") + } + val errorType = typeArguments.get(1) + + if !(errorType.name() == nothing$) && !(errorType.name() == throwable) then + val realClazz = Class.forName(errorType.name().toString(), false, Thread.currentThread().getContextClassLoader) + if (!classOf[Throwable].isAssignableFrom(realClazz)) { + val returnType = info.returnType().toString.replaceAll("<","[").replaceAll(">","]") + val parameters = info.parameters().asScala.map(v => s"${v.name()}:${v.`type`().toString}").mkString(",") + val signature = s"${info.name()}(${parameters}):${returnType}" + + throw new RuntimeException(s"The error type of def ${signature} in ${info.declaringClass()} needs to be either Nothing, a Throwable or subclass of Throwable") + } + } + + + override def isMethodSignatureAsync(info: MethodInfo): Boolean = { + info.returnType().name() == ZIO + } +} diff --git a/zio/deployment/src/test/scala/io/quarkiverse/scala/scala3/zio/test/Scala3ZioDevModeTest.scala b/zio/deployment/src/test/scala/io/quarkiverse/scala/scala3/zio/test/Scala3ZioDevModeTest.scala new file mode 100644 index 0000000..fd8d727 --- /dev/null +++ b/zio/deployment/src/test/scala/io/quarkiverse/scala/scala3/zio/test/Scala3ZioDevModeTest.scala @@ -0,0 +1,23 @@ +package io.quarkiverse.scala.scala3.zio.test; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusDevModeTest; + +class Scala3ZioDevModeTest { + + // Start hot reload (DevMode) test with your extension loaded + @RegisterExtension + val devModeTest: QuarkusDevModeTest = new QuarkusDevModeTest() + .setArchiveProducer(() => ShrinkWrap.create(classOf[JavaArchive])) + + @Test + def writeYourOwnDevModeTest(): Unit = { + // Write your dev mode tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-hot-reload for more information + Assertions.assertTrue(true, "Add dev mode assertions to " + getClass().getName()); + } +} diff --git a/zio/deployment/src/test/scala/io/quarkiverse/scala/scala3/zio/test/Scala3ZioTest.scala b/zio/deployment/src/test/scala/io/quarkiverse/scala/scala3/zio/test/Scala3ZioTest.scala new file mode 100644 index 0000000..b5ef78d --- /dev/null +++ b/zio/deployment/src/test/scala/io/quarkiverse/scala/scala3/zio/test/Scala3ZioTest.scala @@ -0,0 +1,23 @@ +package io.quarkiverse.scala.scala3.zio.test; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +class Scala3ZioTest { + + // Start unit test with your extension loaded + @RegisterExtension + def unitTest: QuarkusUnitTest = new QuarkusUnitTest() + .setArchiveProducer(() => ShrinkWrap.create(classOf[JavaArchive])) + + @Test + def writeYourOwnUnitTest(): Unit = { + // Write your unit tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-extensions for more information + Assertions.assertTrue(true, "Add some assertions to " + getClass().getName()); + } +} diff --git a/zio/integration-tests/pom.xml b/zio/integration-tests/pom.xml new file mode 100644 index 0000000..a0ec7e0 --- /dev/null +++ b/zio/integration-tests/pom.xml @@ -0,0 +1,131 @@ + + + 4.0.0 + + + io.quarkiverse.scala + quarkus-scala3-zio-parent + 999-SNAPSHOT + + quarkus-scala3-zio-integration-tests + Quarkus Scala3 Zio - Integration Tests + + + false + + + + + io.quarkus + quarkus-rest + + + io.quarkiverse.scala + quarkus-scala3-zio + ${project.version} + + + io.quarkiverse.scala + quarkus-scala3-zio-deployment + ${project.version} + + + org.scala-lang + scala3-compiler_3 + ${scala.version} + test + + + org.scala-lang + scala3-library_3 + ${scala.version} + test + + + io.quarkus + quarkus-junit5 + test + + + io.quarkus + quarkus-junit5-internal + test + + + io.rest-assured + rest-assured + test + + + dev.zio + zio_3 + + + + + + src/main/scala + src/test/scala + + + + io.quarkus + quarkus-maven-plugin + + + + build + + + + + + maven-failsafe-plugin + + + + integration-test + verify + + + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + net.alchim31.maven + scala-maven-plugin + + + + + + + native-image + + + native + + + + + + maven-surefire-plugin + + ${native.surefire.skip} + + + + + + false + true + + + + diff --git a/zio/integration-tests/src/main/resources/application.properties b/zio/integration-tests/src/main/resources/application.properties new file mode 100644 index 0000000..e69de29 diff --git a/zio/integration-tests/src/main/scala/io/quarkiverse/scala/scala3/zio/it/CustomThrowable.java b/zio/integration-tests/src/main/scala/io/quarkiverse/scala/scala3/zio/it/CustomThrowable.java new file mode 100644 index 0000000..197934e --- /dev/null +++ b/zio/integration-tests/src/main/scala/io/quarkiverse/scala/scala3/zio/it/CustomThrowable.java @@ -0,0 +1,5 @@ +package io.quarkiverse.scala.scala3.zio.it; + +public class CustomThrowable extends RuntimeException { + +} diff --git a/zio/integration-tests/src/main/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResource.scala b/zio/integration-tests/src/main/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResource.scala new file mode 100644 index 0000000..bfef1a3 --- /dev/null +++ b/zio/integration-tests/src/main/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResource.scala @@ -0,0 +1,65 @@ + +package io.quarkiverse.scala.scala3.zio.it + +import jakarta.enterprise.context.ApplicationScoped +import jakarta.ws.rs.GET +import jakarta.ws.rs.Path +import jakarta.ws.rs.QueryParam +import zio.* + +@Path("/scala3-zio") +@ApplicationScoped +class Scala3ZioResource { + // add some rest methods here + + @GET + @Path("") + def hello(): String = "Hello scala3-zio simple string" + + @GET + @Path("/zio-string") + def zioString: ZIO[String with Int, CustomThrowable, String] = { + import zio._ + for { + _ <- ZIO.sleep(2.seconds) + } yield "Hello ZIO" + } + + + @GET + @Path("/zio-task") + def zioTask(@QueryParam("a") a: String): Task[String] = { + import zio._ + for { + _ <- ZIO.unit + } yield s"Hello ZIO Task: ${a}" + } + + @GET + @Path("/zio-uio") + def zioUIO(@QueryParam("a") a: String): UIO[String] = { + import zio._ + for { + _ <- ZIO.unit + } yield s"Hello ZIO UIO: ${a}" + } + + @GET + @Path("/zio-io") + def zioIO(@QueryParam("a") a: String): IO[CustomThrowable, String] = { + import zio._ + for { + _ <- ZIO.unit + } yield s"Hello ZIO IO: ${a}" + } + +// @GET +// @Path("/zio-wrong-error-type") +// def zioError(a: String): ZIO[Any, Nothing, String] = { +// import zio._ +// for { +// _ <- ZIO.unit +// } yield "Hello ZIO" +// } + +} diff --git a/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Given.scala b/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Given.scala new file mode 100644 index 0000000..6f9e5e7 --- /dev/null +++ b/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Given.scala @@ -0,0 +1,27 @@ +package io.quarkiverse.scala.scala3.zio.it + +import io.restassured.RestAssured.* +import io.restassured.internal.{ResponseSpecificationImpl, ValidatableResponseImpl} +import io.restassured.response.{ExtractableResponse, Response, ValidatableResponse} +import io.restassured.specification.{RequestSender, RequestSpecification, ResponseSpecification} + +class GivenConstructor(givenBlock: RequestSpecification => RequestSpecification): + def When(whenBlock: RequestSpecification => Response): ExpectationConstructor = + ExpectationConstructor(givenBlock, whenBlock) + + class ExpectationConstructor( + givenBlock: RequestSpecification => RequestSpecification, + whenBlock: RequestSpecification => Response + ): + def Then(validatable: ValidatableResponse => Unit) = + val appliedGiven: RequestSpecification = givenBlock.apply(`given`()) + val appliedWhen: Response = whenBlock.apply(appliedGiven) + validatable.apply(appliedWhen.`then`()) + +object Given: + def apply(givenBlock: RequestSpecification => RequestSpecification): GivenConstructor = GivenConstructor(givenBlock) + +def When(whenBlock: RequestSpecification => Response) = + def blankGiven(givenBlock: RequestSpecification): RequestSpecification = `given`() + Given(blankGiven).When(whenBlock) + \ No newline at end of file diff --git a/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResourceIT.scala b/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResourceIT.scala new file mode 100644 index 0000000..2b341c3 --- /dev/null +++ b/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResourceIT.scala @@ -0,0 +1,7 @@ +package io.quarkiverse.scala.scala3.zio.it; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class Scala3ZioResourceIT extends Scala3ZioResourceTest { +} diff --git a/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResourceTest.scala b/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResourceTest.scala new file mode 100644 index 0000000..c81f91d --- /dev/null +++ b/zio/integration-tests/src/test/scala/io/quarkiverse/scala/scala3/zio/it/Scala3ZioResourceTest.scala @@ -0,0 +1,71 @@ +package io.quarkiverse.scala.scala3.zio.it; + + +import org.hamcrest.Matchers.is +import org.junit.jupiter.api.Test +import io.quarkus.test.junit.QuarkusTest +import org.hamcrest.Matchers + +@QuarkusTest +class Scala3ZioResourceTest { + + + @Test + def `test Hello Endpoint`(): Unit = { + Given { + _.params("something", "value") + }.When { + _.get("/scala3-zio").prettyPeek() + }.Then { + _.statusCode(200).body(is("Hello scala3-zio simple string")) + } + } + + @Test + def `test zio-string Endpoint`(): Unit = { + Given { + _.params("something", "value") + }.When { + _.get("/scala3-zio/zio-string").prettyPeek() + }.Then { + _.statusCode(200).body(is("Hello ZIO")) + } + } + + @Test + def `test zio Task Endpoint`(): Unit = { + Given { + _.params("a", "value") + }.When { + _.get("/scala3-zio/zio-task") + }.Then { + _.statusCode(200).body(is("Hello ZIO Task: value")) + } + } + + @Test + def `test zio UIO Endpoint`(): Unit = { + Given { + _.params("a", "value") + }.When { + _.get("/scala3-zio/zio-uio") + }.Then { + _.statusCode(200).body(is("Hello ZIO UIO: value")) + } + } + + @Test + def `test zio IO Endpoint`(): Unit = { + Given { + _.params("a", "value") + }.When { + _.get("/scala3-zio/zio-io") + }.Then { + _.statusCode(200).body(is("Hello ZIO IO: value")) + } + } + + + + +} diff --git a/zio/pom.xml b/zio/pom.xml new file mode 100644 index 0000000..8f6c605 --- /dev/null +++ b/zio/pom.xml @@ -0,0 +1,124 @@ + + + 4.0.0 + + + io.quarkiverse + quarkiverse-parent + 16 + + io.quarkiverse.scala + quarkus-scala3-zio-parent + 999-SNAPSHOT + pom + Quarkus Scala3 Zio - Parent + + + deployment + runtime + + + + 3.12.1 + 17 + UTF-8 + UTF-8 + 3.10.0 + 4.9.1 + 3.3.3 + 2.1.0 + + + + + + io.quarkus + quarkus-bom + ${quarkus.version} + pom + import + + + org.scala-lang + scala3-library_3 + ${scala.version} + + + dev.zio + zio_3 + ${zio.version} + + + + + + src/main/scala + src/test/scala + + + + io.quarkus + quarkus-maven-plugin + ${quarkus.version} + + + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + + + + net.alchim31.maven + scala-maven-plugin + ${scala-maven-plugin.version} + + + + scala-compile-first + process-resources + + add-source + compile + + + + + scala-test-compile + process-test-resources + + add-source + testCompile + + + + + + -Wunused:all + -feature + -deprecation + -Ysemanticdb + + + + + + + + + + it + + + performRelease + !true + + + + integration-tests + + + + diff --git a/zio/runtime/pom.xml b/zio/runtime/pom.xml new file mode 100644 index 0000000..91f01d8 --- /dev/null +++ b/zio/runtime/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + + io.quarkiverse.scala + quarkus-scala3-zio-parent + 999-SNAPSHOT + + quarkus-scala3-zio + Quarkus Scala3 Zio - Runtime + + + + io.quarkus + quarkus-arc + + + + + + + io.quarkus + quarkus-extension-maven-plugin + ${quarkus.version} + + + compile + + extension-descriptor + + + ${project.groupId}:${project.artifactId}-deployment:${project.version} + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + + diff --git a/zio/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/zio/runtime/src/main/resources/META-INF/quarkus-extension.yaml new file mode 100644 index 0000000..9ff048d --- /dev/null +++ b/zio/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -0,0 +1,11 @@ +name: Scala3 Zio +#description: Do something useful. +metadata: + keywords: + - scala + - scala3 + - zio +# guide: https://quarkiverse.github.io/quarkiverse-docs/scala3-zio/dev/ # To create and publish this guide, see https://github.com/quarkiverse/quarkiverse/wiki#documenting-your-extension +# categories: +# - "miscellaneous" +# status: "preview"