-
Notifications
You must be signed in to change notification settings - Fork 0
docs: Document the sbt-uni-crossproject plugin #627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,111 @@ | ||||||||||
| # sbt-uni-crossproject Plugin | ||||||||||
|
|
||||||||||
| `sbt-uni-crossproject` lets one source tree cross-build for **JVM, Scala.js, and | ||||||||||
| Scala Native**. It is a small, uni-owned re-implementation of | ||||||||||
| [portable-scala/sbt-crossproject](https://github.com/portable-scala/sbt-crossproject), | ||||||||||
| which has not been ported to sbt 2.x. | ||||||||||
|
|
||||||||||
| It provides just the surface uni uses: `crossProject(...)` with the | ||||||||||
| **`CrossType.Pure`** layout — shared sources in `<base>/src`, platform-specific | ||||||||||
| code in `<base>/.jvm`, `.js`, and `.native`. | ||||||||||
|
|
||||||||||
| ::: warning sbt 2.x only | ||||||||||
| The plugin targets **sbt 2.x** (its metabuild runs on Scala 3). It is not | ||||||||||
| published for sbt 1.x — if you are on sbt 1.x, use the original | ||||||||||
| `sbt-crossproject` instead. | ||||||||||
| ::: | ||||||||||
|
|
||||||||||
| ::: tip One plugin, all three platforms | ||||||||||
| Unlike upstream's three separate artifacts (`sbt-crossproject` + | ||||||||||
| `sbt-scalajs-crossproject` + `sbt-scala-native-crossproject`), this is a single | ||||||||||
| plugin that depends on both `sbt-scalajs` and `sbt-scala-native` and defines all | ||||||||||
| three platforms. | ||||||||||
| ::: | ||||||||||
|
|
||||||||||
| ## Installation | ||||||||||
|
|
||||||||||
| In `project/plugins.sbt`, add the Scala.js and Scala Native plugins (for their | ||||||||||
| `scalaJSLinkerConfig` / `nativeConfig` settings) and this one: | ||||||||||
|
|
||||||||||
| ```scala | ||||||||||
| addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.22.0") | ||||||||||
| addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.12") | ||||||||||
| addSbtPlugin("org.wvlet.uni" % "sbt-uni-crossproject" % "__UNI_VERSION__") | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| The plugin is triggered automatically, so `crossProject`, the platforms, and | ||||||||||
| `CrossType` are available in `build.sbt` without an explicit `enablePlugins`. | ||||||||||
|
|
||||||||||
| ## Usage | ||||||||||
|
|
||||||||||
| ```scala | ||||||||||
| lazy val core = crossProject(JVMPlatform, JSPlatform, NativePlatform) | ||||||||||
| .crossType(CrossType.Pure) | ||||||||||
| .in(file("core")) | ||||||||||
| .settings(/* shared settings */) | ||||||||||
| .jvmSettings(/* JVM-only */) | ||||||||||
| .jsSettings(/* Scala.js-only */) | ||||||||||
| .nativeSettings(/* Scala Native-only */) | ||||||||||
|
|
||||||||||
| lazy val app = crossProject(JVMPlatform, JSPlatform, NativePlatform) | ||||||||||
| .crossType(CrossType.Pure) | ||||||||||
| .in(file("app")) | ||||||||||
| .dependsOn(core, core % "test") | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| `crossProject` must be assigned directly to a `val` — it derives the project id | ||||||||||
| from the **val name** (just like sbt's own `project`). So `val core = …` defines | ||||||||||
| the sub-projects `coreJVM`, `coreJS`, and `coreNative`, which you reach as | ||||||||||
| `core.jvm`, `core.js`, and `core.native` (e.g. when aggregating or depending on a | ||||||||||
| single platform): | ||||||||||
|
|
||||||||||
| ```scala | ||||||||||
| lazy val root = project | ||||||||||
| .in(file(".")) | ||||||||||
| .aggregate(core.jvm, core.js, core.native, app.jvm, app.js, app.native) | ||||||||||
|
|
||||||||||
| sbt> coreJVM/test | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ::: tip sbt 2.x dependencies | ||||||||||
| On sbt 2.x, `%%` already encodes the platform suffix (`_sjs1` for Scala.js, | ||||||||||
| `_native0.5` for Native), so use `%%` (not the old `%%%`) for your cross-platform | ||||||||||
| library dependencies inside `.settings(...)`. | ||||||||||
| ::: | ||||||||||
|
|
||||||||||
| ## Directory layout (`CrossType.Pure`) | ||||||||||
|
|
||||||||||
| ``` | ||||||||||
| core | ||||||||||
| ├── .js // core/.js/src/main/scala — Scala.js-only sources | ||||||||||
| ├── .jvm // core/.jvm/src/main/scala — JVM-only sources | ||||||||||
| ├── .native // core/.native/src/main/scala — Scala Native-only sources | ||||||||||
| └── src // core/src/main/scala — shared across all platforms | ||||||||||
| // core/src/main/scala-3, scala-2.13, ... — shared, version-specific | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Shared sources live under `<base>/src`. Scala-version-specific shared sources | ||||||||||
| (`src/main/scala-3`, `src/main/scala-2.13`, …) are picked up too when `crossPaths` | ||||||||||
| is enabled (the default). The same structure applies under `src/test` for tests. | ||||||||||
|
|
||||||||||
| ## Supported API | ||||||||||
|
|
||||||||||
| The cross-project value supports the methods uni's own build relies on: | ||||||||||
|
|
||||||||||
| | Method | Description | | ||||||||||
| | ------------------------------------------------- | ------------------------------------------------------------- | | ||||||||||
| | `.crossType(CrossType.Pure \| CrossType.Full)` | Choose the directory layout (default `Pure`) | | ||||||||||
| | `.in(file("..."))` | Set the cross-project base directory | | ||||||||||
| | `.settings(...)` | Settings applied to every platform project | | ||||||||||
| | `.jvmSettings` / `.jsSettings` / `.nativeSettings`| Settings applied to one platform only | | ||||||||||
| | `.configure(...)` / `.jvmConfigure` / `.jsConfigure` / `.nativeConfigure` | Apply `Project => Project` transforms | | ||||||||||
|
Comment on lines
+100
to
+101
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The methods
Suggested change
|
||||||||||
| | `.enablePlugins(...)` / `.disablePlugins(...)` | Enable/disable sbt plugins on every platform project | | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||
| | `.dependsOn(other, other % "test")` | Depend on another cross-project, optionally scoped to a config| | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using the
Suggested change
|
||||||||||
| | `.aggregate(other)` | Aggregate another cross-project | | ||||||||||
| | `.jvm` / `.js` / `.native` | The underlying single-platform `Project` for that platform | | ||||||||||
|
|
||||||||||
| ::: tip Scope | ||||||||||
| Only the `CrossType.Pure` (and `CrossType.Full`) layouts are supported. Upstream | ||||||||||
| features uni does not use — partially-shared sources, the `Dummy` layout, and | ||||||||||
| `withoutSuffixFor` — are intentionally omitted. | ||||||||||
| ::: | ||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In sbt, it is more idiomatic and common to use the
Testconfiguration object (e.g.,core % Test) rather than the string literal"test"(e.g.,core % "test"). Since the scripted tests for this plugin also usecore % Test, updating this example to useTestimproves consistency and follows standard sbt practices.