Setting Initialization

This page outlines the mechanisms by which sbt loads settings for a
particular build, including the hooks where users can control the
ordering of everything.

As stated elsewhere, sbt constructs its initialization graph and task
graph via Setting[_] objects. A setting is something which can take
the values stored at other Keys in the build state, and generates a new
value for a particular build key. sbt converts all registered
Setting[_] objects into a giant linear sequence and compiles them
into a task graph. This task graph is then used to execute your build.

All of sbt’s loading semantics are contained within the
Load.scala file. It is approximately
the following:

The blue circles represent actions happening when sbt loads a project.
We can see that sbt performs the following actions in load:

Compile the user-level project (~/.sbt/<version>/)

a. Load any plugins defined by this project (~/.sbt/<version>/plugins/*.sbt and ~/.sbt/<version>/plugins/project/*.scala)
b. Load all settings defined (~/.sbt/<version>/*.sbt and ~/.sbt/<version>/plugins/*.scala)

projectSettings - These are settings specific to a project. They
are specific to a particular subproject in the build. A plugin
may be contributing its settings to more than on project, in which
case the values are duplicated for each project. You add project
specific settings, eg. in project/build.scala:

After loading/compiling all the build definitions, sbt has a series of
Seq[Setting[_]] that it must order. As shown in the diagram, the
default inclusion order for sbt is:

All AutoPlugin settings

All settings defined in project/Build.scala

All settings defined in the user directory
(~/.sbt/<version>/*.sbt)

All local configurations (build.sbt)

Controlling Initialization

The order which sbt uses to load settings is configurable at a project
level. This means that we can’t control the order of settings added to
Build/Global namespace, but we can control how each project loads, e.g.
plugins and .sbt files. To do so, use the AddSettings class:

This build defines a version string which appends the Scala version if
the current Scala version is not the in the 2.10.x series. Now, when
issuing a release we want to lock down the version. Most tools assume
this can happen by writing a version.sbt file. version.sbt:

version := "1.0.0"

However, when we load this new build, we find that the version in
version.sbt has been overridden by the one defined in
project/Build.scala because of the order we defined for settings, so
the new version.sbt file has no effect.