Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SBT 0.13 taskKey macro doesn't work with [Unit]?

Tags:

scala

sbt

lazy val buildDb = taskKey[Unit]("Initializes the database")

buildDb := {
  (compile in Compile).value
  val s: TaskStreams = streams.value
  s.log.info("Building database")
  try {
    ...
  } catch {
    case e: Throwable =>
      sys.error("Failed to initialize the database: " + e.getMessage)
  }
  s.log.info("Finished building database")
}

This produces the following error

C:\work\server\build.sbt:98: error: type mismatch;
 found   : Unit
 required: T
  s.log.info("Finished building database")
            ^
[error] Type error in expression

But if I define it like this lazy val buildDb = taskKey[String]("Initializes the database") and then add to the last line in the task "Happy end!" string everything seem to work. Am I to blame, or something wrong with the macro?

like image 983
eugen-fried Avatar asked Mar 04 '14 15:03

eugen-fried


1 Answers

The same happened to me. I was able to fix the issue e.g. by adding a : TaskKey[Unit] to the taskKey definition. Here are my findings for sbt 0.13.5:

The following definition is OK (it seems that it is pure luck that this is OK):

lazy val collectJars = taskKey[Unit]("collects JARs")

collectJars := {
  println("these are my JARs:")
  (externalDependencyClasspath in Runtime).value foreach println
}

The following definition (the same as above without the first println) yields the same error "found: Unit, required: T":

lazy val collectJars = taskKey[Unit]("collects JARs")

collectJars := {
  (externalDependencyClasspath in Runtime).value foreach println
}

My findings are that this is definitely something magical: For example, if I indent the line lazy val collectJars = ... by one blank, then it compiles. I would expect (but have not checked) that .sbt and .scala build definitions also behave differently.

However, if you add the type signature, it seems to always compile:

lazy val collectJars: TaskKey[Unit] = taskKey[Unit]("collects JARs")

collectJars := {
  (externalDependencyClasspath in Runtime).value foreach println
}

Last but not least: The issue seems to be specific for TaskKey[Unit]. Unit tasks are not a good idea - in your example, you could at least return Boolean (true for success / false for failure).

like image 158
Georg Avatar answered Oct 19 '22 03:10

Georg