41

有人能解释一下写这两行的区别吗:

resolvers in ThisBuild ++= appResolvers

resolvers in Global ++= appResolvers
4

2 回答 2

31

阅读Scopes以获得完整的解释。

我将引用相关部分:

共有三个范围轴:

  • 子项目轴
  • 依赖配置轴
  • 任务轴

按项目轴确定范围

如果您将多个项目放在一个构建中,则每个项目都需要自己的设置。也就是说,可以根据项目来确定键的范围。

项目轴也可以设置为ThisBuild,这意味着“整个构建”,因此设置适用于整个构建而不是单个项目。当项目未定义项目特定设置时,构建级别设置通常用作后备。

零范围组件

每个范围轴都可以用轴类型的实例填充(类似于Some(_)),或者可以用特殊值 填充轴Zero。所以我们可以Zero认为None.

Zero是所有范围轴的通用后备,但在大多数情况下,它的直接使用应保留给 sbt 和插件作者。

Global是一个设置Zero到所有轴的范围:Zero / Zero / Zero. 换句话说,Global / someKey是 的简写Zero / Zero / Zero / someKey

在构建定义中引用范围

Global / concurrentRestrictions := Seq(
  Tags.limitAll(1)
)

Global / concurrentRestrictions隐式转换为Zero / Zero / Zero / concurrentRestrictions,将所有轴设置为Zero范围组件;任务和配置已经Zero默认,所以这里的效果是制作项目Zero,即定义Zero / Zero / Zero / concurrentRestrictions而不是ProjectRef(uri("file:/tmp/hello/"), "root") / Zero / Zero / concurrentRestrictions

因此,如上所述,Global将所有三个轴设置为,ZeroThisBuild仅将子项目轴设置为ThisBuildThisBuild如果您与其他轴(如配置)结合使用,这可能是有意义的:

> set ThisBuild / Test / name := "test-name"
[info] Defining ThisBuild / Test / name

2020 年 2 月更新:正如 Stefan K 在评论范围委派规则中指出的那样,这是我在上述解释中未包含的一个关键事实。

规则 4:给定一个范围,通过按以下顺序替换子项目轴来搜索委托范围:给定的子项目,ThisBuild然后是Zero

例如,如果发布配置引用projFoo / version,它将按以下顺序查找:

  1. projFoo / version
  2. ThisBuild / version
  3. Global / version

如果默认设置的范围为Global,就像在version设置的情况下(请参阅inspect version),使用其中一个ThisBuild / versionGlobal / version将能够为构建中的所有项目设置版本号。这里的选择ThisBuild几乎是按照惯例。

有时人们可能想要区分这两个范围。首先是源依赖。sbt 有一个内置的支持来依赖跨多个构建的子项目。在这些情况下,使用ThisBuild将防止一个设置溢出到其他构建。

在某些情况下,某些功能专门指全局范围的设置,通常用于配置命令的行为和/或 sbt 本身的行为。Global / concurrentRestrictions就是一个例子。在这种情况下,必须使用Global / concurrentRestrictions.

于 2013-08-19T01:18:35.300 回答
10

这可能会在插件中使用:

resolvers in Global ++= appResolvers

而这可能会出现在您的构建定义中:

resolvers in ThisBuild ++= appResolvers

从而让您覆盖插件提供的全局默认值。

在相同的构建定义中,使用其中任何一个很可能会产生相同的效果,因为它们是委托列表中的最后两个。

于 2015-01-02T10:01:50.197 回答