Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
279 views
in Technique[技术] by (71.8m points)

sbt - What is the difference between ThisBuild and Global scopes?

Can someone explain me the difference between writing these 2 lines:

resolvers in ThisBuild ++= appResolvers

resolvers in Global ++= appResolvers
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Read Scopes for the full explanation.

I'll quote relevant parts:

There are three scope axes:

  • The subproject axis
  • The dependency configuration axis
  • The task axis

Scoping by project axis

If you put multiple projects in a single build, each project needs its own settings. That is, keys can be scoped according to the project.

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.

Zero scope component

Each scope axis can be filled in with an instance of the axis type (analogous to Some(_)), or the axis can be filled in with the special value Zero. So we can think of Zero as None.

Zero is a universal fallback for all scope axes, but its direct use should be reserved to sbt and plugin authors in most cases.

Global is a scope that sets Zero to all axes: Zero / Zero / Zero. In other words, Global / someKey is a shorthand for Zero / Zero / Zero / someKey.

Referring to scopes in a build definition

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

(Global / concurrentRestrictions implicitly converts to Zero / Zero / Zero / concurrentRestrictions, setting all axes to Zero scope component; the task and configuration are already Zero by default, so here the effect is to make the project Zero, that is, define Zero / Zero / Zero / concurrentRestrictions rather than ProjectRef(uri("file:/tmp/hello/"), "root") / Zero / Zero / concurrentRestrictions)

So as written above, Global sets all three axes to Zero whereas ThisBuild sets only the subproject axis to ThisBuild. This might make sense if you combine ThisBuild with other axis like configuration:

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

Update February 2020: As Stefan K noted in the comment scope delegation rule is a key fact that I didn't include in the above explanation.

Rule 4: Given a scope, delegate scopes are searched by substituting the subproject axis in the following order: the given subproject, ThisBuild, and then Zero.

For example, if publishing configuration refers to projFoo / version, it would look in the order of:

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

If the default setting is scoped to Global, like in the case of version setting (see inspect version), using either ThisBuild / version or Global / version would be able to set a version number for all projects in the build. The choice of ThisBuild here is almost by convention.

There are times where one might want to distinguish the two scoping. First is for source dependencies. sbt has a built-in support to depend on subprojects across multiple builds. In these cases, using ThisBuild would prevent one setting from spilling over to other builds.

There are also cases where some feature specifically refers to a globally scoped setting, often to configure the behavior of a command and/or the behavior of sbt itself. Global / concurrentRestrictions is an example of that. In this case, one must use Global / concurrentRestrictions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...