Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is Def.task and .taskValue in SBT?

Tags:

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.

like image 598
Alexander Arendar Avatar asked Oct 20 '25 16:10

Alexander Arendar


1 Answers

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:

  • Tasks
  • Tasks/Settings: Motivation
  • Execution semantics of tasks
  • Sequencing tasks
like image 176
laughedelic Avatar answered Oct 25 '25 03:10

laughedelic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!