2017-01-20 4 views
1

Рассмотрим простой SBT файл:Почему sbt выполняет избыточную задачу?

lazy val task = taskKey[Unit]("task") 

lazy val p = project.in(file(".")).settings(
    packageBin in Compile := { 
    println("compile") 
    (packageBin in Compile).value 
    }, 
    task := { 
    sys.props.get("conf") match { 
     case Some(t) => println(t) 
     case None => println((packageBin in Compile).value) 
    } 
    } 
) 

И два пробегов SBT:

sbt task 
[info] Set current project to p (in build file:...) 
compile 
.../target/scala-2.10/p_2.10-0.1-SNAPSHOT.jar 
[success] Total time: 1 s, completed Jan 20, 2017 1:11:48 PM 

sbt -Dconf=xxx task 
[info] Set current project to p (in build file:...) 
compile 
xxx 
[success] Total time: 1 s, completed Jan 20, 2017 1:13:39 PM 

Вы можете видеть, что задача компиляции выполняется в обоих случаях, думал, что это выглядит, как она должна быть выполнена только в первый.

Мои вопросы:

  1. Почему это происходит? Я думаю, что это связано с реализацией макросоматики, но мое понимание макросов scala и внутренних компонентов sbt слишком мало, чтобы объяснить, почему именно.
  2. Есть ли обходное решение, кроме определения двух разных задач?
  3. Я использую неправильный шаблон, опираясь на опоры?

ответ

2

Это происходит потому, что ключ task определяется в терминах ключа packageBin in Compile. Поэтому, даже если его значение используется только в одной ветви кода, его эффект (println) выполняется в обоих случаях.

Решение предназначено для использования taskDyn: http://www.scala-sbt.org/0.13/docs/Tasks.html#Dynamic+Computations+with

Смежные вопросы