settings(inThisBuild(...)) 在 sbt 中是什么意思?

What does settings(inThisBuild(...)) mean in sbt?

我刚刚使用 scalaxb 模板生成了一个 sbt 项目:

sbt new eed3si9n/scalaxb.g8

我得到了这个 build.sbt 文件:

lazy val root = (project in file(".")).
  enablePlugins(ScalaxbPlugin).
  settings(inThisBuild(List(
    organization  := "com.example",
    scalaVersion  := "2.13.2",
    crossScalaVersions := Seq("2.13.2", "2.12.12")
  ))).
  settings(
    name          := "test-scalaxb",
    libraryDependencies ++= Seq(dispatch, scalaXml, scalaParser)
  ).
  settings(
    scalaxbDispatchVersion in (Compile, scalaxb) := dispatchV,
    scalaxbPackageName in (Compile, scalaxb)     := "generated"
  )

settings 中的 inThisBuild 是什么意思(第 3 行)?我通常在 build.sbt 文件的根目录下看到它,而不是在 settings 下。它与根本没有 inThisBuild(例如上面文件中的 namelibraryDependencies)有何不同?

来自 sbt 文档:

The project axis can also be set to ThisBuild, which means the “entire build”, so a setting applies to the entire build rather than a single project. Build-level settings are often used as a fallback when a project doesn’t define a project-specific setting.

第一个设置适用于整个项目中的所有子项目,而第二个仅适用于根项目

What does the inThisBuild within settings mean?

语义上等同于:

ThisBuild / organization  := "com.example"
ThisBuild / scalaVersion  := "2.13.2"
ThisBuild / crossScalaVersions := Seq("2.13.2", "2.12.12")

今天推荐使用ThisBuild / organization。我应该更新我的旧 Giter8 模板。

元详情

sbt 在设置序列上有一个名为 inConfig(Compile)(List(setting1, ...))map 的辅助函数,将它们的范围限定为 Compile 配置,这对于定义一次设置序列并在中重复使用它很有用CompileTest

2015 年,Dale contributed 另一个名为 inThisBuild(List(setting1, ...)) 的辅助函数,类似于 inConfig(Compile)(...) 将列表范围限定为 ThisBuild 范围。这是由于 sbt 0.13,其中作用域被写为 organization in ThisBuild 而不是 2018 年引入的斜杠语法。

I usually see it at the root level of the build.sbt file, not under settings.

build.sbt 的根级别写入称为 裸样式 build.sbt。使用 bare 样式在语义上编写设置序列(包括 inThisBuild(...))与将它们放在构建的根子项目(file(".") 处的子项目)中的 .settings(...) 中是相同的。在 2016 中,当我将该行添加到 eed3si9n/scalaxb.g8 时,我想我比现在 更多 致力于摆脱裸体风格 build.sbt今天,所以我拒绝直接在build.sbt上写inThisBuild(...),而是放在.settings(...)中。

如上所述,我在 2018 年引入了斜杠语法,这让我开始使用裸样式使用 ThisBuild / scalaVersion(并且仅适用于 ThisBuild / ...Global / ... 设置)所以它会与 shell 语法相同。

构建范围的设置

How is it different from not having inThisBuild at all (e.g. name and libraryDependencies in above file)?

参见Build-wide settings

To factor out common settings across multiple projects, define the settings scoped to ThisBuild. The limitation is that the right-hand side needs to be a pure value or settings scoped to Global or ThisBuild, and there are no default settings scoped to subprojects.

ThisBuild 基本上是提供的特殊子项目名称,因此您可以为构建定义默认设置。当你定义一个或多个子项目时,当子项目没有定义 scalaVersion 时,它会回退到 ThisBuild / scalaVersion.