1. Appending values

Appending values 

Appending to previous values: += and ++= 

Assignment with := is the simplest transformation, but keys have other methods as well. If the T in SettingKey[T] is a sequence, i.e. the key’s value type is a sequence, you can append to the sequence rather than replacing it.

  • += will append a single element to the sequence.
  • ++= will concatenate another sequence.

For example, the key Compile / sourceDirectories has a Seq[File] as its value. By default this key’s value would include src/main/scala. If you wanted to also compile source code in a directory called source (since you just have to be nonstandard), you could add that directory:

Compile / sourceDirectories += new File("source")

Or, using the file() function from the sbt package for convenience:

Compile / sourceDirectories += file("source")

(file() just creates a new File.)

You could use ++= to add more than one directory at a time:

Compile / sourceDirectories ++= Seq(file("sources1"), file("sources2"))

Where Seq(a, b, c, ...) is standard Scala syntax to construct a sequence.

To replace the default source directories entirely, you use := of course:

Compile / sourceDirectories := Seq(file("sources1"), file("sources2"))

When settings are undefined 

Whenever a setting uses :=, +=, or ++= to create a dependency on itself or another key’s value, the value it depends on must exist. If it does not, sbt will complain. It might say “Reference to undefined setting“, for example. When this happens, be sure you’re using the key in the scope that defines it.

It’s possible to create cycles, which is an error; sbt will tell you if you do this.

Tasks based on other keys’ values 

You can compute values of some tasks or settings to define or append a value for another task. It’s done by using Def.task as an argument to :=, +=, or ++=.

As a first example, consider appending a source generator using the project base directory and compilation classpath.

Compile / sourceGenerators += Def.task {
  myGenerator(baseDirectory.value, (Compile / managedClasspath).value)
}

Appending with dependencies: += and ++= 

Other keys can be used when appending to an existing setting or task, just like they can for assigning with :=.

For example, say you have a coverage report named after the project, and you want to add it to the files removed by clean:

cleanFiles += file("coverage-report-" + name.value + ".txt")