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

时间:2017-09-18 04:13:02

标签: 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

  

许多案例类被替换为使用Contraband生成的伪案例类。将.copy(foo = xxx)迁移到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,但我想在某些时候我不得不这样做,也许有些有帮助的人会在那时回答这个问题。

1 个答案:

答案 0 :(得分:15)

(这个答案已经编辑了有关sbt 1.1.0+和sbt-crossproject 0.3.1+的信息,这显着简化了整个事情。)

使用sbt 1.1.0及更高版本,您可以使用.withId("core")。但是对于sbt-crossproject 0.3.1+,情况会更好,见下文。

我不知道如何更改Project的ID,但这里也是解决原始问题的完全不同的方式,即{{1} } / core代替coreJS。我们的想法是自定义coreJVM/coreJS以使用您想要开头的ID。

首先,您需要使用sbt-crossproject。这是新的标准"用于跨多个平台的编译,由来自Scala Native和我自己(来自Scala.js)的@densh共同设计。 Scala.js 1.x将始终使用sbt-crossproject,但也可以将sbt-crossproject与Scala.js 0.6.x一起使用。为此,请关注the instructions in the readme。特别是,不要忘记"阴影"部分:

crossProject

sbt-crossproject比Scala.js更灵活。硬编码// Shadow sbt-scalajs' crossProject and CrossType from Scala.js 0.6.x import sbtcrossproject.{crossProject, CrossType} 。这意味着您可以更轻松地自定义它。特别是,它具有crossProject的通用概念,定义了任何给定平台的行为方式。

对于跨JVM / JS项目,新式Platform调用将是

crossProject

从sbt-crossproject 0.3.1开始,您可以简单地告诉它不要为您的某个平台添加平台后缀。在您的情况下,您希望避免使用JVM平台的后缀,因此您可以编写:

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.0及之前

lazy val coreBase = crossProject(JVMPlatform, JSPlatform) .withoutSuffixFor(JVMPlatform) .crossType(CrossType.Pure) ... lazy val core = coreBase.jvm lazy val coreJS = coreBase.js JVMPlatform不是ADT;它们采用OO风格设计。这意味着您可以创建自己的。特别是,您可以创建自己的JSPlatform,其作用与JVMPlatform相同,但不会在项目ID中添加后缀:

JVMPlatformNoSuffix

现在还不够,因为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(...)采取行动,而不是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

无需明确修补项目ID。