How to conditionally execute SBT task

710 Views Asked by At

I have an alternative way of completing an existing expensive task, though I don't know until runtime if I'll do it that way. (For example, a file cache.)

How do I do this?


For example, packageBin:

packageBin in Compile := Def.taskDyn {
  if (canDoItMyWay) {
    doItMyWayTask
  } else {
    Defaults.packageTask
  }
}.value

This doesn't work if it executes the latter path:

$ sbt packageBin
[trace] Stack trace suppressed: run last compile:packageBin for the full output.
[error] (util-2_10/compile:packageBin) sbt.Init$RuntimeUndefined: References to undefined settings at runtime.
1

There are 1 best solutions below

3
On

the following works for me:

val canDoItMyWay: Boolean = ...

//regular method. Not a task
def doItMyWay: File = ...

packageBin in Compile := {
    if(canDoItMyWay) doItMyWay
    else (packageBin in Compile).value
}

no need to use dynamic tasks here. note that .value will only work in sbt 0.13+

also, note that I didn't use a special Task for it. just regular code. judging by the name: doItMyWayTask implies you defined a task. if you use a custom task, then:

  • is it needed? why a task? does it depends on other settings/tasks?
  • if it must be a task, make sure to not have cyclic dependency here, i.e. it should not depend on packageBin