我写了一个SBT自动插件MyPlugin.scala
:
package com.abhi
import sbt._
import sbt.Keys._
object MyPlugin extends AutoPlugin {
object autoImport {
val helloTask = taskKey[Unit]("says hello")
val byeTask = taskKey[Unit]("bye task")
}
import autoImport._
override lazy val projectSettings = Seq(
helloTask := {
val dir = sourceManaged.value
val cp = (dependencyClasspath in Compile).value
val r = (runner in Compile).value
val s = streams.value
val rd = (resourceDirectory in Compile).value
val sd = (sourceDirectory in Compile).value
println(s"Here to say hello $dir $cp $r $s $rd $sd")
},
byeTask := {
val dir = sourceManaged.value
val cp = (dependencyClasspath in Compile).value
val r = (runner in Compile).value
val s = streams.value
val rd = (resourceDirectory in Compile).value
val sd = (sourceDirectory in Compile).value
println(s"Here to say bye $dir $cp $r $s $rd $sd")
}
)
}
这有效,我可以使用这个插件。但是helloTask
和byeTask
的实现会有点长,所以我不想在MyPlugin.scala
内编写实现。
相反,我想创建两个单独的文件HelloTask.scala
和ByeTask.scala
,然后在那里编写相应的实现。
我查看了Custom Settings的SBT文档,所有示例都始终在插件本身内实现任务。
如何在helloTask
文件之外编写byeTask
和MyPlugin.scala
的实现?还有如何在HelloTask
和ByeTask
之间分享一些逻辑。
以下几行在两个任务之间是通用的,我只想写一次
val dir = sourceManaged.value
val cp = (dependencyClasspath in Compile).value
val r = (runner in Compile).value
val s = streams.value
val rd = (resourceDirectory in Compile).value
val sd = (sourceDirectory in Compile).value
答案 0 :(得分:2)
分离任务实施是一种常见的良好做法。它在Tasks documentation中提到。您可以使用Def.task
宏编写实现:
def taskImpl(args: ...): Def.Initialize[Task[...]] = Def.task {
...
}
然后使用不同的参数设置不同的任务键:
override def projectSettings = Seq(
taskA := taskImpl("A").value,
taskB := taskImpl("B").value,
)
在你的情况下,你可以这样做:
def saySmthImpl(msg: String): Def.Initialize[Task[Unit]] = Def.task {
val dir = sourceManaged.value
val cp = (dependencyClasspath in Compile).value
val r = (runner in Compile).value
val s = streams.value
val rd = (resourceDirectory in Compile).value
val sd = (sourceDirectory in Compile).value
println(s"$msg $dir $cp $r $s $rd $sd")
}
如果需要,您可以将此实现保留在单独的文件中。在插件定义中,您可以像这样使用它:
override def projectSettings = Seq(
helloTask := saySmthImpl("Here to say hello").value,
byeTask := saySmthImpl("Here to say bye").value,
)
您应该记住,使用.value
访问其他设置或任务只能在某些范围内完成,例如Def.task
或Def.setting
或使用{{设置密钥时1}}。这限制了(或者更确切地说指示)在不同任务实现之间共享逻辑的方式。