Skip to content

Commit

Permalink
Rename macro and SBT plugin (#4)
Browse files Browse the repository at this point in the history
* Rename macro to WitExport
* Rename GolemScalaPlugin to WasmComponentPlugin
* Rename directory
  • Loading branch information
danieletorelli authored May 8, 2024
1 parent 29a798d commit 680acf0
Show file tree
Hide file tree
Showing 18 changed files with 151 additions and 146 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
golem-scala
===========
sbt-wasm-component
==================

Avoid any boilerplate in your project by using just one annotation to export your Golem worker from Scala to JS.

Setup
-----

Add golem-scala as a dependency in `project/plugins.sbt`:
Add sbt-wasm-component as a dependency in `project/plugins.sbt`:

```scala
addSbtPlugin("cloud.golem" % "golem-scala" % "x.y.z")
addSbtPlugin("cloud.golem" % "sbt-wasm-component" % "x.y.z")
```

Usage
-----

Golem-scala is automatically loaded, it just needs to be enabled with `enablePlugins(GolemScalaPlugin)` in your `build.sbt`:
The WASM component plugin is automatically loaded, it just needs to be enabled with `enablePlugins(WasmComponentPlugin)` in your `build.sbt`:

```scala
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.13.13"

lazy val root = (project in file("."))
.enablePlugins(GolemScalaPlugin)
.enablePlugins(WasmComponentPlugin)
```

Then you will be able to annotate your Golem worker object with the `@cloud.golem.Worker` annotation:
Then you will be able to annotate your Golem worker object with the `@cloud.golem.WitExport` annotation:

```scala
package example

@cloud.golem.Worker
@cloud.golem.WitExport
object ShoppingCart { self =>

def initializeCart(userId: String): String = {
Expand All @@ -45,5 +45,5 @@ object ShoppingCart { self =>

```

Once done that, it will be enough to run `sbt fullLinkJS` and the plugin will take care of exporting your worker in JS.
Once done that, it will be enough to run `sbt wasmComponent` and the plugin will take care of exporting your worker in WASM.

4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ThisBuild / organization := "cloud.golem"

lazy val root = (project in file("."))
.settings(
name := "golem-scala",
name := "sbt-wasm-component",
addSbtPlugin("org.scala-js" % "sbt-scalajs" % Versions.scalaJS)
)
.settings(scriptedLaunchOpts += s"-Dplugin.version=${version.value}")
Expand All @@ -15,7 +15,7 @@ lazy val root = (project in file("."))

lazy val macros = project
.settings(
name := "golem-scala-macros",
name := "sbt-wasm-component-macros",
crossScalaVersions += Versions.scala2_13,
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import scala.language.experimental.macros
import scala.reflect.macros.whitebox

@compileTimeOnly("Enable macro paradise to expand macro annotations")
final class Worker extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro WorkerExport.impl
final class WitExport extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro WitExportMacro.impl
}

object WorkerExport {
object WitExportMacro {
def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._

Expand Down
40 changes: 0 additions & 40 deletions src/main/scala/cloud/golem/GolemScalaPlugin.scala

This file was deleted.

86 changes: 0 additions & 86 deletions src/main/scala/cloud/golem/GolemScalaPluginInternal.scala

This file was deleted.

40 changes: 40 additions & 0 deletions src/main/scala/cloud/golem/WasmComponentPlugin.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cloud.golem

import sbt.*
import org.scalajs.sbtplugin.ScalaJSPlugin
import sbt.plugins.JvmPlugin

object WasmComponentPlugin extends AutoPlugin {
object autoImport {
lazy val wasmComponentOutputDirectory = SettingKey[File](
"wasmComponentOutputDirectory",
"Output directory",
KeyRanks.Invisible
)
lazy val wasmComponentWitPath = SettingKey[File](
"wasmComponentWitPath",
"Path to the wit file",
KeyRanks.Invisible
)
lazy val wasmComponentPackageName = SettingKey[String](
"wasmComponentPackageName",
"Package name",
KeyRanks.Invisible
)
lazy val wasmComponentWitBindgen =
taskKey[Seq[File]](
"Runs golem-scalajs-wit-bindgen to generate WIT bindings"
)
lazy val wasmComponent =
taskKey[Unit]("Runs componentize-js on the generated ScalaJS file")
}

override def trigger: PluginTrigger = allRequirements

override def requires: Plugins = JvmPlugin && ScalaJSPlugin

override lazy val projectSettings: Seq[Setting[?]] =
WasmComponentPluginInternal.baseSettings ++
WasmComponentPluginInternal.scalaJsSettings ++
WasmComponentPluginInternal.macroParadiseSettings
}
89 changes: 89 additions & 0 deletions src/main/scala/cloud/golem/WasmComponentPluginInternal.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package cloud.golem

import sbt.*
import sbt.Keys.*
import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport.*

private[golem] object WasmComponentPluginInternal {
import WasmComponentPlugin.autoImport.*

private object Versions {
val macros = "0.1.0"
val scalaMacrosParadise = "2.1.1"
}

lazy val baseSettings: Seq[Setting[?]] = {
lazy val wasmComponentWitFullPath =
Def
.task(
wasmComponentWitPath.value / s"${wasmComponentPackageName.value}.wit"
)
Def.settings(
wasmComponentOutputDirectory := target.value / "dist",
wasmComponentWitPath := (ThisBuild / baseDirectory).value / "wit",
wasmComponentPackageName := moduleName.value,
wasmComponentWitBindgen := {
if (!wasmComponentWitFullPath.value.exists()) {
sys.error(s"""
|'${wasmComponentWitFullPath.value.getAbsolutePath}' does not exist.
|Make sure 'wasmComponentPackageName' is set correctly in your build.sbt
""".stripMargin)
} else {
val wasmComponentWitBindgenOutput = (Compile / sourceManaged).value / "scala" / wasmComponentPackageName.value / "Api.scala"
import scala.sys.process.*

val output = Seq(
"bash",
"-xc",
s"golem-scalajs-wit-bindgen -w ${wasmComponentWitFullPath.value} -p ${wasmComponentPackageName.value}"
).!!

IO.write(wasmComponentWitBindgenOutput, output)
Seq(wasmComponentWitBindgenOutput)
}
},
wasmComponent := {
import scala.sys.process.*
Seq("bash", "-xc", "npm install").!!
Seq("bash", "-xc", "npm run build").!!
},
wasmComponent := (wasmComponent dependsOn (Compile / fullLinkJS)).value,
Compile / sourceGenerators += Def.taskIf {
if (wasmComponentWitFullPath.value.exists())
wasmComponentWitBindgen.value
else {
println(
s"""
|'${wasmComponentWitFullPath.value.getAbsolutePath}' does not exist.
|Make sure 'wasmComponentPackageName' is set correctly in your build.sbt""".stripMargin
)
Nil
}
}.taskValue
)
}

lazy val scalaJsSettings: Seq[Setting[?]] =
Def.settings(
scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.ESModule) },
Compile / fullLinkJS / scalaJSLinkerOutputDirectory := wasmComponentOutputDirectory.value,
Compile / fastLinkJS / scalaJSLinkerOutputDirectory := wasmComponentOutputDirectory.value,
libraryDependencies += "cloud.golem" %% "sbt-wasm-component-macros" % Versions.macros
)

lazy val macroParadiseSettings: Seq[Setting[?]] = Def.settings(
scalacOptions ++= {
if (scalaVersion.value.startsWith("2.13")) Seq("-Ymacro-annotations")
else Nil
},
libraryDependencies ++= {
if (scalaVersion.value.startsWith("2.12")) {
Seq(
compilerPlugin(
"org.scalamacros" % "paradise" % Versions.scalaMacrosParadise cross CrossVersion.full
)
)
} else Nil
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ ThisBuild / scalaVersion := "2.13.13"
ThisBuild / crossScalaVersions += "2.12.19"

lazy val root = (project in file("."))
.enablePlugins(GolemScalaPlugin)
.enablePlugins(WasmComponentPlugin)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
sys.props.get("plugin.version") match {
case Some(version) => addSbtPlugin("cloud.golem" % "golem-scala" % version)
case Some(version) =>
addSbtPlugin("cloud.golem" % "sbt-wasm-component" % version)
case _ =>
sys.error("""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package example

@cloud.golem.Worker
@cloud.golem.WitExport
object ShoppingCart { self =>

def initializeCart(userId: String): String = {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ ThisBuild / scalaVersion := "2.13.13"
ThisBuild / crossScalaVersions += "2.12.19"

lazy val root = (project in file("."))
.enablePlugins(GolemScalaPlugin)
.enablePlugins(WasmComponentPlugin)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
sys.props.get("plugin.version") match {
case Some(version) => addSbtPlugin("cloud.golem" % "golem-scala" % version)
case Some(version) =>
addSbtPlugin("cloud.golem" % "sbt-wasm-component" % version)
case _ =>
sys.error("""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package example

@cloud.golem.Worker
@cloud.golem.WitExport
object ShoppingCart extends Api { self =>

def initializeCart(userId: String): WitResult[String, String] = {
Expand Down
File renamed without changes.

0 comments on commit 680acf0

Please sign in to comment.