Sbt 插件在其他任务之前/之后运行任务

Won*_*nay 0 scala sbt

我知道,我看到在标准任务之前/之后自动运行自定义任务,但它似乎已经过时了。我还发现了一个任务的前/后挂钩的 SBT,但它没有任何代码示例。

我在SBT 0.13.17

所以我想运行我的任务MyBeforeTaskMyAfterTask以后的其他任务自动说Compile

因此,当您这样做时,sbt compile我希望看到:

...log...
This is my before test text
...compile log...
This is my after test text
Run Code Online (Sandbox Code Playgroud)

所以我需要:

object MyPlugin extends AutoPlugin {
  object autoImport {
     val MyBeforeTask = taskKey[Unit]("desc...")
     val MyAfterTask = taskKey[Unit]("desc...")
  }

  import autoImport._

  override def projectSettings: Seq[Def.Setting[_]] = {
     MyBeforeTask := {
       println("This is my before test text")
     },
     MyAfterTask := {
       println("This is my after test text")
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

所以我想我需要这样的东西dependsOnin但我不知道如何设置它们。

Vla*_*eev 5

不可能为特定任务配置在给定任务之后运行,因为这不是任务依赖模型的工作方式 - 当您指定任务时,它的依赖关系和它本身将被执行,但是没有办法定义“之后”的依赖。但是,您可以使用动态任务来模拟它。

要在另一个任务之前运行某个任务,您可以使用dependsOn

compile in Compile := (compile in Compile).dependsOn(myBeforeTask).value
Run Code Online (Sandbox Code Playgroud)

这在两个任务之间建立了依赖关系,从而确保myBeforeTask将在compile in Compile.


请注意,有一种更通用的方法可以让多个任务一个接一个地运行:

aggregateTask := Def.sequential(task1, task2, task3, task4).value
Run Code Online (Sandbox Code Playgroud)

Def.sequential依赖于动态任务机制,它在运行时建立任务之间的依赖关系。但是,这种机制有一些限制,特别是不能引用要执行的任务列表中定义的任务,因此不能用于Def.sequential扩充现有任务:

compile in Compile := Def.sequential(myBeforeTask, compile in Compile).value
Run Code Online (Sandbox Code Playgroud)

此定义将在运行时失败并显示奇怪的错误消息,这基本上意味着您的任务依赖关系图中有一个循环。但是,对于某些用例,它非常有用。


但是,要一个一个地运行某个任务,您必须使用Def.taskDyn以下命令定义动态任务依赖项:

compile in Compile := Def.taskDyn {
  val result = (compile in Compile).value
  Def.task {
    val _ = myAfterTask.value
    result
  }
}.value
Run Code Online (Sandbox Code Playgroud)

Def.taskDyn接受一个必须返回 a 的块,该块Def.Initialize[Task[T]]将用于在主体Def.taskDyn完成后实例化稍后运行的任务。这允许动态计算任务,并在运行时建立任务之间的依赖关系。然而,正如我上面所说,这会导致在运行时发生非常奇怪的错误,这通常是由依赖图中的循环引起的。

因此,包含“before”和“after”任务的完整示例如下所示:

compile in Compile := Def.taskDyn {
  val result = (compile in Compile).value
  Def.task {
    val _ = myAfterTask.value
    result
  }
}.dependsOn(myBeforeTask).value
Run Code Online (Sandbox Code Playgroud)