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执行任务,因为bypassessbt的强项
直接调用任务将结束依赖关系
系统、并行执行系统等
并且可以导致race conditions
小心运行任务。它在 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 执行了两次。