Alexander Arendar
Alexander Arendar

Reputation: 3435

What is Def.task and .taskValue in SBT?

I am reading SBT docs quite thoroughly now and there is a brief mention of Def.task and taskValue but there is no explanation so far. They say here following:

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 and taskValue as an argument to :=, +=, or ++=. 

And provide following code snippet:

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

This brings more questions than answers for me. How is that different from regular dependency of some SBT task on another task? When should I use this macro? etc.

I have also tried to check scaladoc but without any success really. That part of code is not documented well.

Upvotes: 4

Views: 947

Answers (1)

laughedelic
laughedelic

Reputation: 6460

I think this particular example in the introductory part of documentation is unnecessarily complicated. In this example you have to use .taskValue just because sourceGenerators value type is Seq[Task[Seq[File]]], so you have to add a task to it, not the value of that task.

A simpler example for that "Tasks based on other keys’ values" is

homepage := Some(
  url(s"https://github.com/${organization.value}/${name.value}")
)

In the right part of :=/+=/++=/~= operators you can use other tasks values with simple .value suffix. Writing

foo := bar.value + 1

is the same as

foo := Def.task { bar.value + 1 }.value

In this simple example it's just unnecessary, but Def.task becomes useful when you want to separate task implementation from the task key setting:

def fooTask(n: Int): Def.Initialize[Task[Int]] = Def.task {
  bar.value + n
}

So Def.task allows you to write a task definition and use other tasks/settings inside (with .value). Then you can evaluate this task definition when you set the corresponding task key somewhere else (in your project settings):

foo := fooTask(5).value

But if you need to refer to the task definition itself without evaluating it, you can use .taskValue instead of .value, like in your example. See documentation on generating sources for more information about sourceGenerators.

Here are some other relevant parts of the sbt documentation about tasks:

Upvotes: 8

Related Questions