diff --git a/.gitignore b/.gitignore index 02d27cc..f3f9fbb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .idea/ target/ node_modules +cli/src/main/resources/dist/ diff --git a/build.sbt b/build.sbt index 4e8d8e4..24d7c0d 100644 --- a/build.sbt +++ b/build.sbt @@ -1,5 +1,9 @@ +import BuildEnvPlugin.autoImport +import BuildEnvPlugin.autoImport.BuildEnv import xerial.sbt.Sonatype.autoImport.sonatypeCredentialHost +import java.io.InputStream + lazy val scala213 = "2.13.6" lazy val scala3 = "3.0.0" @@ -26,21 +30,23 @@ inThisBuild( lazy val supportedScalaVersions = List(scala213) -val animusVersion = "0.1.7" -val boopickleVerison = "1.3.2" -val fansiVersion = "0.2.14" -val laminarVersion = "0.13.0" -val laminextVersion = "0.13.5" -val postgresVersion = "42.2.20" -val sttpVersion = "3.3.6" -val zioHttpVersion = "1.0.0.0-RC17" -val zioJsonVersion = "0.1.5" -val zioMagicVersion = "0.3.3" -val zioNioVersion = "1.0.0-RC11" -val zioProcessVersion = "0.4.0" -val zioVersion = "1.0.9" -val zioQueryVersion = "0.2.9" -val quillVersion = "3.7.0" +val animusVersion = "0.1.9" +val boopickleVerison = "1.3.2" +val fansiVersion = "0.2.14" +val laminarVersion = "0.13.1" +val laminextVersion = "0.13.10" +val postgresVersion = "42.2.23" +val quillVersion = "3.7.2" +val scalaJavaTimeVersion = "2.3.0" +val shoconVersion = "1.0.0" +val sttpVersion = "3.3.13" +val zioHttpVersion = "1.0.0.0-RC17" +val zioJsonVersion = "0.1.5" +val zioMagicVersion = "0.3.6" +val zioNioVersion = "1.0.0-RC11" +val zioProcessVersion = "0.4.0" +val zioVersion = "1.0.10" +val zioQueryVersion = "0.2.9" val sharedSettings = Seq( addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.13.0" cross CrossVersion.full), @@ -138,8 +144,8 @@ lazy val cliFrontend = project libraryDependencies ++= Seq( "io.github.kitlangton" %%% "animus" % animusVersion, "com.raquo" %%% "laminar" % laminarVersion, - "io.github.cquiroz" %%% "scala-java-time" % "2.3.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.3.0", + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion, "io.laminext" %%% "websocket" % laminextVersion, "com.softwaremill.sttp.client3" %%% "core" % sttpVersion, "com.softwaremill.sttp.client3" %%% "monix" % sttpVersion @@ -192,6 +198,7 @@ lazy val coreJS = core.js lazy val coreJVM = core.jvm lazy val examples = crossProject(JSPlatform, JVMPlatform) + .enablePlugins(ShoconPlugin) .in(file("examples")) .settings( name := "zio-app-examples", @@ -220,9 +227,27 @@ lazy val examples = crossProject(JSPlatform, JVMPlatform) scalaJSUseMainModuleInitializer := true, libraryDependencies ++= Seq( "com.raquo" %%% "laminar" % laminarVersion, - "io.github.cquiroz" %%% "scala-java-time" % "2.3.0", - "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.3.0" - ) + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.github.cquiroz" %%% "scala-java-time-tzdb" % scalaJavaTimeVersion, + "org.akka-js" %%% "shocon" % shoconVersion + ), + (Compile / compile) := (Compile / compile).dependsOn(shoconConcat).value, + shoconConcatFile := { + autoImport.buildEnv.value match { + case BuildEnv.Production => + (Compile / packageBin / artifactPath).value / "zio-app-examples-opt/shocon.conf" + case _ => + (Compile / packageBin / artifactPath).value / "shocon.conf" + } + }, + shoconFilter := { + autoImport.buildEnv.value match { + case BuildEnv.Production => + tuple: (String, InputStream) => tuple._1.contains("resources/prod") + case _ => + tuple: (String, InputStream) => tuple._1.contains("resources/dev") + } + } ) .dependsOn(core) diff --git a/cli/src/main/g8/build.sbt b/cli/src/main/g8/build.sbt index cbcacdc..2dd18ed 100644 --- a/cli/src/main/g8/build.sbt +++ b/cli/src/main/g8/build.sbt @@ -1,17 +1,27 @@ +import BuildEnvPlugin.autoImport +import BuildEnvPlugin.autoImport.BuildEnv + +import java.io.InputStream + name := "$name$" description := "$description$" version := "0.0.1" -val animusVersion = "0.1.9" -val laminarVersion = "0.13.0" -val quillZioVersion = "3.7.1" -val sttpVersion = "3.3.6" -val zioAppVersion = "0.2.5" -val zioConfigVersion = "1.0.6" -val zioHttpVersion = "1.0.0.0-RC17" -val zioJsonVersion = "0.1.5" -val zioMagicVersion = "0.3.3" -val zioVersion = "1.0.9" +val animusVersion = "0.1.9" +val boopickleVerison = "1.3.2" +val laminarVersion = "0.13.1" +val laminextVersion = "0.13.10" +val postgresVersion = "42.2.23" +val quillZioVersion = "3.7.2" +val scalaJavaTimeVersion = "2.3.0" +val shoconVersion = "1.0.0" +val sttpVersion = "3.3.13" +val zioAppVersion = "0.2.6" +val zioConfigVersion = "1.0.6" +val zioHttpVersion = "1.0.0.0-RC17" +val zioJsonVersion = "0.1.5" +val zioMagicVersion = "0.3.6" +val zioVersion = "1.0.10" val sharedSettings = Seq( addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.13.0" cross CrossVersion.full), @@ -23,7 +33,7 @@ val sharedSettings = Seq( ), libraryDependencies ++= Seq( "io.github.kitlangton" %% "zio-app" % zioAppVersion, - "io.suzaku" %%% "boopickle" % "1.3.2", + "io.suzaku" %%% "boopickle" % boopickleVerison, "dev.zio" %%% "zio" % zioVersion, "dev.zio" %%% "zio-streams" % zioVersion, "dev.zio" %%% "zio-macros" % zioVersion, @@ -50,7 +60,7 @@ lazy val backend = project "dev.zio" %% "zio-config-magnolia" % zioConfigVersion, "io.d11" %% "zhttp" % zioHttpVersion, "com.softwaremill.sttp.client3" %% "httpclient-backend-zio" % sttpVersion, - "org.postgresql" % "postgresql" % "42.2.8", + "org.postgresql" % "postgresql" % postgresVersion, "io.getquill" %% "quill-jdbc-zio" % quillZioVersion ) ) @@ -58,7 +68,7 @@ lazy val backend = project lazy val frontend = project .in(file("frontend")) - .enablePlugins(ScalaJSPlugin) + .enablePlugins(ScalaJSPlugin, ShoconPlugin) .settings( scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.ESModule) }, scalaJSLinkerConfig ~= { _.withSourceMap(false) }, @@ -66,11 +76,31 @@ lazy val frontend = project libraryDependencies ++= Seq( "io.github.kitlangton" %%% "animus" % animusVersion, "com.raquo" %%% "laminar" % laminarVersion, - "io.github.cquiroz" %%% "scala-java-time" % "2.2.1", - "io.laminext" %%% "websocket" % "0.13.5" + "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion, + "io.laminext" %%% "websocket" % laminextVersion, + "org.akka-js" %%% "shocon" % shoconVersion ) ) .settings(sharedSettings) + .settings( + (Compile / compile) := (Compile / compile).dependsOn(shoconConcat).value, + shoconConcatFile := { + autoImport.buildEnv.value match { + case BuildEnv.Production => + (Compile / packageBin / artifactPath).value / "prod/shocon.conf" + case _ => + (Compile / packageBin / artifactPath).value / "dev/shocon.conf" + } + }, + shoconFilter := { + autoImport.buildEnv.value match { + case BuildEnv.Production => + tuple: (String, InputStream) => tuple._1.contains("resources/prod") + case _ => + tuple: (String, InputStream) => tuple._1.contains("resources/dev") + } + } + ) .dependsOn(shared) lazy val shared = project diff --git a/cli/src/main/g8/deploy.sh b/cli/src/main/g8/deploy.sh index 889d29c..870197b 100755 --- a/cli/src/main/g8/deploy.sh +++ b/cli/src/main/g8/deploy.sh @@ -1,4 +1,5 @@ -sbt frontend/fullLinkJS +BUILD_ENV=prod sbt frontend/fullLinkJS yarn exec vite -- build cp dist/index.html dist/200.html -surge ./dist '$name$.surge.sh' \ No newline at end of file +cp frontend/target/scala-2.13/frontend*jar/prod/shocon.conf dist/assets/shocon.conf +surge ./dist '$name$.surge.sh' diff --git a/cli/src/main/g8/frontend/src/main/resources/dev/application.conf b/cli/src/main/g8/frontend/src/main/resources/dev/application.conf new file mode 100644 index 0000000..c44abbf --- /dev/null +++ b/cli/src/main/g8/frontend/src/main/resources/dev/application.conf @@ -0,0 +1 @@ +zio.app.backendUri = "api" diff --git a/cli/src/main/g8/frontend/src/main/resources/prod/application.conf b/cli/src/main/g8/frontend/src/main/resources/prod/application.conf new file mode 100644 index 0000000..26d8c19 --- /dev/null +++ b/cli/src/main/g8/frontend/src/main/resources/prod/application.conf @@ -0,0 +1 @@ +zio.app.backendUri = "https://changeme.wrong" diff --git a/cli/src/main/g8/project/BuildEnvPlugin.scala b/cli/src/main/g8/project/BuildEnvPlugin.scala new file mode 100644 index 0000000..ccd9aaf --- /dev/null +++ b/cli/src/main/g8/project/BuildEnvPlugin.scala @@ -0,0 +1,44 @@ +import sbt.Keys._ +import sbt._ +import sbt.plugins.JvmPlugin + +/** sets the build environment */ +object BuildEnvPlugin extends AutoPlugin { + + // make sure it triggers automatically + override def trigger = AllRequirements + override def requires = JvmPlugin + + object autoImport { + object BuildEnv extends Enumeration { + val Production, Test, Development = Value + } + + val buildEnv = settingKey[BuildEnv.Value]("the current build environment") + } + import autoImport._ + + override def projectSettings: Seq[Setting[_]] = Seq( + buildEnv := { + sys.props + .get("env") + .orElse(sys.env.get("BUILD_ENV")) + .flatMap { + case "prod" => Some(BuildEnv.Production) + case "test" => Some(BuildEnv.Test) + case "dev" => Some(BuildEnv.Development) + case _ => None + } + .getOrElse(BuildEnv.Development) + }, + // give feed back + onLoadMessage := { + // depend on the old message as well + val defaultMessage = onLoadMessage.value + val env = buildEnv.value + s"""|$defaultMessage + |Running in build environment: $env""".stripMargin + } + ) + +} diff --git a/cli/src/main/g8/project/plugins.sbt b/cli/src/main/g8/project/plugins.sbt index 38ba41d..8d142e3 100644 --- a/cli/src/main/g8/project/plugins.sbt +++ b/cli/src/main/g8/project/plugins.sbt @@ -1,3 +1,4 @@ -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.6.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.0") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.8.1") addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") +addSbtPlugin("org.akka-js" % "sbt-shocon" % "1.0.0") diff --git a/core/js/src/main/scala/zio/app/FrontendUtils.scala b/core/js/src/main/scala/zio/app/FrontendUtils.scala index 406d77b..4cd0ae0 100644 --- a/core/js/src/main/scala/zio/app/FrontendUtils.scala +++ b/core/js/src/main/scala/zio/app/FrontendUtils.scala @@ -15,13 +15,13 @@ object FrontendUtils { implicit val exPickler: CompositePickler[Throwable] = exceptionPickler private val sttpBackend = - FetchZioBackend(fetchOptions = FetchOptions(credentials = None, mode = Some(RequestMode.`same-origin`))) + FetchZioBackend(fetchOptions = FetchOptions(credentials = None, mode = Some(RequestMode.cors))) - def fetch[E: Pickler, A: Pickler](service: String, method: String): IO[E, A] = - fetchRequest[E, A](bytesRequest.get(uri"api/$service/$method")) + def fetch[E: Pickler, A: Pickler](uriPrefix: String, service: String, method: String): IO[E, A] = + fetchRequest[E, A](bytesRequest.get(uri"$uriPrefix/$service/$method")) - def fetch[E: Pickler, A: Pickler](service: String, method: String, value: ByteBuffer): IO[E, A] = - fetchRequest[E, A](bytesRequest.post(uri"api/$service/$method").body(value)) + def fetch[E: Pickler, A: Pickler](uriPrefix: String, service: String, method: String, value: ByteBuffer): IO[E, A] = + fetchRequest[E, A](bytesRequest.post(uri"$uriPrefix/$service/$method").body(value)) def fetchRequest[E: Pickler, A: Pickler](request: Request[Array[Byte], Any]): IO[E, A] = sttpBackend @@ -40,22 +40,27 @@ object FrontendUtils { } } - def fetchStream[E: Pickler, A: Pickler](service: String, method: String): Stream[E, A] = + def fetchStream[E: Pickler, A: Pickler](uriPrefix: String, service: String, method: String): Stream[E, A] = { ZStream .unwrap { basicRequest - .get(uri"api/$service/$method") + .get(uri"$uriPrefix/$service/$method") .response(asStreamAlwaysUnsafe(ZioStreams)) .send(sttpBackend) .orDie .map(resp => transformZioResponseStream[E, A](resp.body)) } + } - def fetchStream[E: Pickler, A: Pickler](service: String, method: String, value: ByteBuffer): Stream[E, A] = - ZStream + def fetchStream[E: Pickler, A: Pickler]( + uriPrefix: String, + service: String, + method: String, + value: ByteBuffer + ): Stream[E, A] = ZStream .unwrap { basicRequest - .post(uri"api/$service/$method") + .post(uri"$uriPrefix/$service/$method") .body(value) .response(asStreamAlwaysUnsafe(ZioStreams)) .send(sttpBackend) diff --git a/core/shared/src/main/scala/zio/app/internal/BackendUtils.scala b/core/shared/src/main/scala/zio/app/internal/BackendUtils.scala index 8404764..7be2879 100644 --- a/core/shared/src/main/scala/zio/app/internal/BackendUtils.scala +++ b/core/shared/src/main/scala/zio/app/internal/BackendUtils.scala @@ -13,7 +13,13 @@ import java.nio.ByteBuffer object BackendUtils { implicit val exPickler: CompositePickler[Throwable] = exceptionPickler - private val bytesContent: Header = Header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.BYTES) + private val bytesContent: Header = Header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.BYTES) + private val accessControlAllowOrigin: Header = Header(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*") + private val accessControlAllowMethods: Header = Header(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS, "POST") + private val accessControlAllowHeaders: Header = + Header(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, "Authorization, Content-Type") + + private val corsHeaders = List(accessControlAllowOrigin, accessControlAllowMethods, accessControlAllowHeaders) def makeRoute[R, E: Pickler, A: Pickler, B: Pickler]( service: String, @@ -22,17 +28,21 @@ object BackendUtils { ): HttpApp[R, Nothing] = { val service0 = service val method0 = method - Http.collectM { case post @ Method.POST -> Root / `service0` / `method0` => - post.content match { - case HttpData.CompleteData(data) => - val byteBuffer = ByteBuffer.wrap(data.toArray) - val unpickled = Unpickle[A].fromBytes(byteBuffer) - call(unpickled) - .map(ZioResponse.succeed) - .catchAllCause(causeToResponseZio[E](_)) - .map(pickle[ZioResponse[E, B]](_)) - case _ => UIO(Response.ok) - } + Http.collectM { + case post @ Method.POST -> Root / `service0` / `method0` => + post.content match { + case HttpData.CompleteData(data) => + val byteBuffer = ByteBuffer.wrap(data.toArray) + val unpickled = Unpickle[A].fromBytes(byteBuffer) + call(unpickled) + .map(ZioResponse.succeed) + .catchAllCause(causeToResponseZio[E](_)) + .map(pickle[ZioResponse[E, B]](_)) + case _ => UIO(Response.ok) + + } + case Method.OPTIONS -> Root / `service0` / `method0` => + UIO(Response.http(status = Status.OK, headers = corsHeaders)) } } @@ -48,7 +58,10 @@ object BackendUtils { .map(ZioResponse.succeed) .catchAllCause(causeToResponseZio[E](_)) .map(pickle[ZioResponse[E, A]](_)) - } + + case Method.OPTIONS -> Root / `service0` / `method0` => + UIO(Response.http(status = Status.OK, headers = corsHeaders)) + } } def makeRouteStream[R, E: Pickler, A: Pickler, B: Pickler]( @@ -66,7 +79,10 @@ object BackendUtils { makeStreamResponse(call(unpickled)) case _ => Response.ok } - } + + case Method.OPTIONS -> Root / `service0` / `method0` => + Response.http(status = Status.OK, headers = corsHeaders) + } } def makeRouteNullaryStream[R, E: Pickler, A: Pickler]( @@ -78,6 +94,9 @@ object BackendUtils { val method0 = method Http.collect { case Method.GET -> Root / `service0` / `method0` => makeStreamResponse(call) + + case Method.OPTIONS -> Root / `service0` / `method0` => + Response.http(status = Status.OK, headers = corsHeaders) } } @@ -86,7 +105,7 @@ object BackendUtils { val byteBuf = Unpooled.wrappedBuffer(bytes) val httpData = HttpData.fromByteBuf(byteBuf) - Response.http(status = Status.OK, headers = List(bytesContent), content = httpData) + Response.http(status = Status.OK, headers = List(bytesContent, accessControlAllowOrigin), content = httpData) } private def makeStreamResponse[A: Pickler, E: Pickler, R]( @@ -100,7 +119,7 @@ object BackendUtils { Chunk.fromByteBuffer(Pickle.intoBytes(a)) } - Response.http(content = HttpData.fromStream(responseStream)) + Response.http(headers = List(accessControlAllowOrigin), content = HttpData.fromStream(responseStream)) } private def causeToResponseStream[E: Pickler](cause: Cause[E]): UStream[ZioResponse[E, Nothing]] = diff --git a/core/shared/src/main/scala/zio/app/internal/macros/Macros.scala b/core/shared/src/main/scala/zio/app/internal/macros/Macros.scala index d5f1e97..9307813 100644 --- a/core/shared/src/main/scala/zio/app/internal/macros/Macros.scala +++ b/core/shared/src/main/scala/zio/app/internal/macros/Macros.scala @@ -11,10 +11,11 @@ private[app] class Macros(val c: blackbox.Context) { import c.universe._ def client_impl[Service: c.WeakTypeTag]: c.Tree = { + val serviceType = c.weakTypeOf[Service] assertValidMethods(serviceType) - val appliedTypes = getAppliedTypes(serviceType) + val appliedTypes = getAppliedTypes[Service](serviceType) def applyType(tpe: Type): Type = tpe.map { tpe => appliedTypes.getOrElse(tpe.typeSymbol, tpe) } val methodDefs = serviceType.decls.collect { case method: MethodSymbol => @@ -39,17 +40,17 @@ private[app] class Macros(val c: blackbox.Context) { method.returnType.dealias.typeConstructor <:< weakTypeOf[ZStream[Any, Nothing, Any]].typeConstructor val request = - if (isStream) { - if (params.isEmpty) - q"_root_.zio.app.FrontendUtils.fetchStream[$errorType, $returnType](${serviceType.finalResultType.toString}, ${methodName.toString})" - else - q"_root_.zio.app.FrontendUtils.fetchStream[$errorType, $returnType](${serviceType.finalResultType.toString}, ${methodName.toString}, Pickle.intoBytes($pickleType))" - } else { - if (params.isEmpty) - q"_root_.zio.app.FrontendUtils.fetch[$errorType, $returnType](${serviceType.finalResultType.toString}, ${methodName.toString})" - else - q"_root_.zio.app.FrontendUtils.fetch[$errorType, $returnType](${serviceType.finalResultType.toString}, ${methodName.toString}, Pickle.intoBytes($pickleType))" - } + if (isStream) { + if (params.isEmpty) + q"""_root_.zio.app.FrontendUtils.fetchStream[$errorType, $returnType](config.getString("zio.app.backendUri"), ${serviceType.finalResultType.toString}, ${methodName.toString})""" + else + q"""_root_.zio.app.FrontendUtils.fetchStream[$errorType, $returnType](config.getString("zio.app.backendUri"), ${serviceType.finalResultType.toString}, ${methodName.toString}, Pickle.intoBytes($pickleType))""" + } else { + if (params.isEmpty) + q"""_root_.zio.app.FrontendUtils.fetch[$errorType, $returnType](config.getString("zio.app.backendUri"), ${serviceType.finalResultType.toString}, ${methodName.toString})""" + else + q"""_root_.zio.app.FrontendUtils.fetch[$errorType, $returnType](config.getString("zio.app.backendUri"), ${serviceType.finalResultType.toString}, ${methodName.toString}, Pickle.intoBytes($pickleType))""" + } q"def $methodName(...$valDefs): ${applyType(method.returnType)} = $request" } @@ -60,6 +61,9 @@ new ${serviceType.finalResultType} { import _root_.boopickle.Default._ import _root_.zio.app.internal.CustomPicklers._ import _root_.zio.app.FrontendUtils.exPickler + import _root_.com.typesafe.config.{Config, ConfigFactory} + + private val config = ConfigFactory.load() ..$methodDefs } @@ -118,7 +122,7 @@ import _root_.zhttp.http._ import _root_.boopickle.Default._ import _root_.zio.app.internal.CustomPicklers._ import _root_.zio.app.internal.BackendUtils.exPickler - + $block """) diff --git a/examples/js/src/main/resources/dev/application.conf b/examples/js/src/main/resources/dev/application.conf new file mode 100644 index 0000000..c44abbf --- /dev/null +++ b/examples/js/src/main/resources/dev/application.conf @@ -0,0 +1 @@ +zio.app.backendUri = "api" diff --git a/examples/js/src/main/resources/prod/application.conf b/examples/js/src/main/resources/prod/application.conf new file mode 100644 index 0000000..a7b4b75 --- /dev/null +++ b/examples/js/src/main/resources/prod/application.conf @@ -0,0 +1 @@ +zio.app.backendUri = "http://localhost:8088" diff --git a/project/BuildEnvPlugin.scala b/project/BuildEnvPlugin.scala new file mode 100644 index 0000000..ccd9aaf --- /dev/null +++ b/project/BuildEnvPlugin.scala @@ -0,0 +1,44 @@ +import sbt.Keys._ +import sbt._ +import sbt.plugins.JvmPlugin + +/** sets the build environment */ +object BuildEnvPlugin extends AutoPlugin { + + // make sure it triggers automatically + override def trigger = AllRequirements + override def requires = JvmPlugin + + object autoImport { + object BuildEnv extends Enumeration { + val Production, Test, Development = Value + } + + val buildEnv = settingKey[BuildEnv.Value]("the current build environment") + } + import autoImport._ + + override def projectSettings: Seq[Setting[_]] = Seq( + buildEnv := { + sys.props + .get("env") + .orElse(sys.env.get("BUILD_ENV")) + .flatMap { + case "prod" => Some(BuildEnv.Production) + case "test" => Some(BuildEnv.Test) + case "dev" => Some(BuildEnv.Development) + case _ => None + } + .getOrElse(BuildEnv.Development) + }, + // give feed back + onLoadMessage := { + // depend on the old message as well + val defaultMessage = onLoadMessage.value + val env = buildEnv.value + s"""|$defaultMessage + |Running in build environment: $env""".stripMargin + } + ) + +} diff --git a/project/plugins.sbt b/project/plugins.sbt index b413554..0925a23 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,8 +1,9 @@ -addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.0") +addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.1") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.8.1") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.1") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.0") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.27") addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.7") addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.5.3") +addSbtPlugin("org.akka-js" % "sbt-shocon" % "1.0.0") diff --git a/release.sh b/release.sh index b5eb5f8..f1f1352 100755 --- a/release.sh +++ b/release.sh @@ -2,7 +2,6 @@ sbt cliFrontend/fullLinkJS cd cli-frontend yarn exec -- vite build cd .. -mv ./cli-frotnend/dist ./cli/src/main/resources/dist sbt cli/nativeImage cd cli/target/native-image