scala - 如何在 SBT 1.0 中更改项目的 ID?

标签 scala sbt

我有一堆 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) to withFoo(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 及之前
JVMPlatformJSPlatform不是 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 采取行动,而不是其他任何 PlatformJVMPlatformNoSuffix .因此,您还必须重新定义它:

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/

相关文章:

sbt - 它 :scalastyle not working for integration tests' folder

scala - 使用经过身份验证的 repo 覆盖 sbt 默认解析器?

scala - 如何更改 SBT 命令中的设置?

scala - 为什么 sbt 会给出 Akka 和 ScalaTest 依赖项的多个依赖项警告?

scala - 值切片不是 play.api.libs.iteratee.Enumerator 的成员

scala - 如何忽略 Scala 中的 "-Ywarn-unused"警告?

Scala:如何编写 sortBy 所采用的函数的类型?

scala - 如何在终端中从 build.sbt 获取值

java - SBT 在尝试运行简单的 "Hello!"示例脚本时给出 java.lang.NullPointerException

scala - 如何在 sbt 中为我的项目设置系统属性?