我有一堆 SBT 0.13 项目定义,如下所示:
lazy val coreBase = crossProject.crossType(CrossType.Pure).in(file("core"))
.settings(...)
.jvmConfigure(_.copy(id = "core"))
.jsConfigure(_.copy(id = "coreJS"))
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
(主要是因为我对必须维护 Scala.js 构建感到不满,并且不想在每次更改项目时都输入
JVM
后缀等。)这不会在 SBT 1.0 中编译,因为
Project
没有 copy
现在的方法。好的,让我们检查一下 the migration guide .
Many of the case classes are replaced with pseudo case classes generated using Contraband. Migrate
.copy(foo = xxx)
towithFoo(xxx)
.
酷,让我们试试吧。
build.sbt:100: error: value withId is not a member of sbt.Project
.jvmConfigure(_.withId("core"))
^
所以我asked on Gitter并得到了蟋蟀。
1.0 API 文档的链接现在实际上指向了一些东西,这很好,但它们在 this case 中不是很有帮助,并试图阅读 SBT 源代码让我头疼。我并不急于更新到 1.0,但我想我将不得不在某个时候更新,也许届时会有一些有用的人回答这个问题。
最佳答案
(此答案已使用有关 sbt 1.1.0+ 和 sbt-crossproject 0.3.1+ 的信息进行编辑,这大大简化了整个过程。)
对于 sbt 1.1.0 及更高版本,您可以使用 .withId("core")
.但是 sbt-crossproject 0.3.1+ 更好,见下文。
我不知道如何更改 Project
的 ID ,但这里还有一种完全不同的方法来解决您的原始问题,即有 core
/coreJS
而不是 coreJVM/coreJS
.思路是定制crossProject
使用您想要开始的 ID。
首先,您需要使用 sbt-crossproject .它是跨多个平台编译的新“标准”,由来自 Scala Native 的 @densh 和我自己(来自 Scala.js)共同设计。 Scala.js 1.x 将始终使用 sbt-crossproject,但也可以将 sbt-crossproject 与 Scala.js 0.6.x 一起使用。为此,请关注 the instructions in the readme .特别是,不要忘记“阴影”部分:
// Shadow sbt-scalajs' crossProject and CrossType from Scala.js 0.6.x
import sbtcrossproject.{crossProject, CrossType}
sbt-crossproject 比 Scala.js 的硬编码更灵活
crossProject
.这意味着您可以更轻松地对其进行自定义。特别是,它有一个通用的概念 Platform
,定义任何给定平台的行为方式。对于跨 JVM/JS 项目,新式
crossProject
调用将是lazy val coreBase = crossProject(JVMPlatform, JSPlatform)
.crossType(CrossType.Pure)
.in(file("core"))
.settings(...)
.jvmConfigure(_.copy(id = "core"))
.jsConfigure(_.copy(id = "coreJS"))
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
从 sbt-crossproject 0.3.1 开始,您可以简单地告诉它不要为您的平台之一添加平台后缀。在你的情况下,你想避免 JVM 平台的后缀,所以你会写:
lazy val coreBase = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
...
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
这就是您需要做的一切!
旧答案,适用于 sbt-crossproject 0.3.0 及之前
JVMPlatform
和 JSPlatform
不是 ADT;它们以 OO 风格设计。这意味着您可以创建自己的。特别是,您可以创建自己的 JVMPlatformNoSuffix
这与 JVMPlatform
的作用相同但没有为项目 ID 添加后缀:import sbt._
import sbtcrossproject._
case object JVMPlatformNoSuffix extends Platform {
def identifier: String = "jvm"
def sbtSuffix: String = "" // <-- here is the magical empty string
def enable(project: Project): Project = project
val crossBinary: CrossVersion = CrossVersion.binary
val crossFull: CrossVersion = CrossVersion.full
}
现在这还不够,因为
.jvmSettings(...)
和 friend 被定义为对 JVMPlatform
采取行动,而不是其他任何 Platform
如 JVMPlatformNoSuffix
.因此,您还必须重新定义它:implicit def JVMNoSuffixCrossProjectBuilderOps(
builder: CrossProject.Builder): JVMNoSuffixCrossProjectOps =
new JVMNoSuffixCrossProjectOps(builder)
implicit class JVMNoSuffixCrossProjectOps(project: CrossProject) {
def jvm: Project = project.projects(JVMPlatformNoSuffix)
def jvmSettings(ss: Def.SettingsDefinition*): CrossProject =
jvmConfigure(_.settings(ss: _*))
def jvmConfigure(transformer: Project => Project): CrossProject =
project.configurePlatform(JVMPlatformNoSuffix)(transformer)
}
一旦您在构建中拥有所有这些(隐藏在
project/JVMPlatformNoSuffix.scala
中,以免污染 .sbt
文件),您可以将上述跨项目定义为:lazy val coreBase = crossProject(JVMPlatformNoSuffix, JSPlatform)
.crossType(CrossType.Pure)
.in(file("core"))
.settings(...)
lazy val core = coreBase.jvm
lazy val coreJS = coreBase.js
无需显式修补项目 ID。
关于scala - 如何在 SBT 1.0 中更改项目的 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46271505/