Quick Guide to master SBT

A quick guide also servers as a reminder for myself

Build Definitions

SBT uses a DSL in build.sbt to define your build as a collection of key-value pairs. The core syntax follows three patterns:

  • key := value (sets a value)
  • key += value (appends a single value)
  • key ++= values (appends multiple values)

Key Types

SBT has three fundamental key types:

  • SettingKey[T]: Evaluated once when the build is loaded
  • TaskKey[T]: Evaluated each time it's called (like a function)
  • InputKey[T]: Accepts command-line input when called

You can write Scala code directly in build.sbt, but top-level classes and objects must be placed in Scala files under the project/ directory.

Task Graph

Tasks and settings form a Directed Acyclic Graph (DAG) through their dependencies. When SBT evaluates a task, it first evaluates all of its dependencies, ensuring proper execution order. This dependency-based evaluation model is central to SBT's power.

Dependencies between tasks are defined using the .value method. This tells SBT that one task depends on another:


lazy val taskA = taskKey[String]("A sample task")
lazy val taskB = taskKey[String]("A task that depends on taskA")

taskA := "Hello"
taskB := {
  val resultFromA = taskA.value // This creates a dependency on taskA
  s"${resultFromA} World"
}

Scopes

Keys in SBT are scoped, meaning the same key can have different values in different contexts. Scopes have three dimensions:

  1. Project: Defines which project the key applies to (e.g., core, api, common in multi-module projects)
  2. Configuration: Specifies the context or scope as maven does. (e.g., Scala source directory in Compile is src/main/scala, while in Test is src/test/scala)
  3. Task: Indicates which task the key is being used with

Understanding scopes is crucial for effective SBT usage as they allow the same key to be used differently across your build.

Common Commands

  • sbt compile: Compiles the main sources
  • sbt test: Runs all tests
  • sbt run: Runs the main class
  • sbt console: Starts a Scala REPL with project classes and dependencies
  • sbt package: Creates a JAR file
  • sbt assembly: Build an assembly jar if sbt-assembly plugin is added
  • sbt publishLocal: Publishes the artifact to the local Ivy repository
  • sbt dependencyTree: show the dependencies tree
  • inspect: use inspect command in sbt shell to understand a task or a setting, like inspect compile

References