NightWolf
NightWolf

Reputation: 7794

sbt - Adding a task key defined outside of build.sbt

If I define a SBT task key outside of my build.sbt file as a Scala class in the project folder, how can I import that task

So in ./project/MyTask.scala I have;

import sbt.Keys._
import sbt._

object MyTask {
  lazy val uname = settingKey[String]("Your name")
  lazy val printHi = taskKey[Unit]("print Hi")
  printHi := { println(s"hi ${name.value}") }
}

Then in ./build.sbt I have;

import MyTask._

uname := "Joe"

Then when I run sbt printHi I get an error that the task cannot be found. Running show uname also works. When I define printHi in build.sbt directly without the object import everything works as expected.

I need so somehow add this task to the build.sbt file. How can I do this?

Upvotes: 4

Views: 1349

Answers (1)

Dale Wijnand
Dale Wijnand

Reputation: 6102

The issue is that your expression printHi := { println(s"hi ${name.value}") } isn't associated to anything.

First off, everything in sbt is a transformation, in this case (:=) overrides any previous setting of printHi to the definition you give (println(s"hi ${name.value}")). But by not associating that expression (which is a Setting[Task[Unit]]) to anything (for instance to a project, or as a value that then gets attached to a project) it just gets evaluated in the construction of the MyTask object and then thrown away.

One way to do this is to put that setting (printHi := println(s"hi ${name.value}")), in a Seq[Setting[_]] that you then pull into build.sbt:

project/MyTask.scala

import sbt._, Keys._

object MyTask {
  val printHi = taskKey[Unit]("prints Hi")
  val myTaskSettings = Seq[Setting[_]](
    printHi := println(s"hi ${name.value}")
  )
}

build.sbt

import MyTask._

myTaskSettings

Another way is to define MyTask to be a mini plugin that lives in project/. You can see an example of this in PgpCommonSettings.

Upvotes: 6

Related Questions