我如何两次运行任务,第一次使用build.sbt
中定义的设置,第二次使用其他设置?代码将是这样的:
val childSetting = settingKey[String]("Some setting")
val childTask = taskKey[String]("Child task")
childTask := ???
val parentTask = taskKey[String]("Parent task")
parentTask := {
val initial = childTask.value
// Do some stuff
// Run childTask again with different setting
// Do other stuff
}
sbt deduplicates的任务,例如,给定以下parentTask
的定义
val childSetting = settingKey[String]("Some setting")
childSetting := "Live long and prosper"
val childTask = taskKey[String]("Child task")
childTask := {
val x = childSetting.value
println(x)
x
}
val parentTask = taskKey[String]("Parent task")
parentTask := {
val initial = childTask.value
val another = childTask.value
initial
}
似乎我们在childTask
中执行了两次
parentTask := {
val initial = childTask.value
val another = childTask.value
initial
}
无论执行sbt parentTask
,我们都会看到副作用println(x)
输出
Live long and prosper
仅一次。因此,似乎我们不能简单地使用value
宏,这是执行任务的推荐方法。尝试像这样使用runTask
parentTask := {
val st = state.value
val extracted = Project.extract(st)
val (st2, initial) = extracted.runTask(childTask, st)
val st3 = extracted.appendWithSession(Seq(childSetting := "nuqneH"), st2)
val (st4, another) = Project.extract(st3).runTask(childTask, st3)
another
}
现在执行sbt parentTask
会运行println(x)
的childTask
副作用两次,每次都以不同状态运行
Live long and prosper
...
nuqneH
但是不建议直接使用runTask
直接执行任务,因为它具有bypasses sbt的优势
直接调用任务将绕过依赖关系的终点系统,并行执行系统等。
并可能导致race conditions
小心runTask。它在sbt的任务图之外执行。能够导致比赛条件等。请参阅:sbt / sbt#2970
例如,虽然给定命令的用法类似discouraged,也可以尝试定义命令
commands += Command.command("foo") { state =>
"childTask" :: """set childSetting := "nuqneH"""" :: "childTask" :: state
}
执行sbt foo
输出
Live long and prosper
...
nuqneH
我们看到println(x)
的childTask
副作用执行了两次。