SBT TaskKey If Statement

时间:2014-03-10 16:46:39

标签: if-statement sbt

我正在使用SBT 0.13。我遇到了一个问题,以下玩具示例展示了这个问题:

lazy val nativeOne = TaskKey[Unit]( "nativeOne", "One" )
lazy val nativeTwo = TaskKey[Unit]( "nativeTwo", "Two" )

lazy val testProj = Project(
    id = "testProj",
    base = file( "." ),
    settings = Defaults.defaultSettings ++ Seq(
        scalaVersion := "2.10.2",
        nativeOne :=
        {
            println( "Native one"
        },  
        nativeTwo :=
        {
            if ( true )
            {
                println( "Native two" )
            }
            else
            {
                val n1 = nativeOne.value
            }
        }
    )
)

如果我进入sbt并运行nativeTwo

> nativeTwo
Native one
Native two

为什么会这样?为什么评估false分支?是不允许在TaskKeys中进行分支?

1 个答案:

答案 0 :(得分:6)

在sbt 所有依赖项是在任务运行之前并行计算的。如果你要构建一个你所拥有的图表,那就是:

nativeOne
   ^
   |
nativeTwo

您要做的是订购任务。在sbt中,我们尝试促进返回其他任务直接使用的结果的任务,因此.value。这样做不是直接运行任务,而是说“给我这个其他任务的结果”。

理解sbt语法的最佳方式是s​​cala-async项目的模仿。您的代码类似于以下异步代码:

nativeOne = async {
  println( "Native one")
}
nativeTwo = async {
  if(true) println("Native Two")
  else await(nativeOne)
}

在那里,你只是说“等待价值,如果它还没有计算出来,那就更明显了。”

如果你想有选择地执行一个任务,你需要在sbt的Task[_]层执行此操作,这有点冗长。我们正在使用“动态任务”。这是选择在运行时实际运行哪些任务的那个。

因此,您需要使用Def.taskDyn方法,该方法允许您按照定义的顺序组合任务。您将使用toTask的{​​{1}}方法自行处理任务。这不是处理任务产生的。这是一个例子TaskKey

build.sbt

然后在sbt控制台中:

val taskOne = taskKey[Int]("test")

val taskTwo = taskKey[Int]("test2")

val taskThree = taskKey[Int]("test3")

val switchEm = settingKey[Boolean]("switch 'em")

switchEm := true

taskOne := { println("taskOne"); 1 }

taskTwo := { println("taskTwo"); 2 }

taskThree := Def.taskDyn({
  if(switchEm.value) taskTwo.toTask
  else taskOne.toTask
}).value

另请注意,您不会在inspect命令中看到更正的依赖项,因为依赖项是动态添加的:

> reload
[info] Loading project definition from /home/jsuereth/projects/sbt/test-projects/project
[info] Set current project to test-projects (in build file:/home/jsuereth/projects/sbt/test-projects/)
> taskThree
2