Sbt плагин запускает задачи до / после другой задачи - PullRequest
0 голосов
/ 14 ноября 2018

Я знаю, я видел Автоматический запуск пользовательской задачи до / после стандартной задачи , но она выглядит устаревшей. Я также нашел SBT до / после хуков для задачи , но у него нет примера кода.

Я на SBT 0.13.17.

Поэтому я хочу, чтобы мои задачи MyBeforeTask и MyAfterTask запускались автоматически после других задач, говорит Compile.

Так что, когда вы делаете sbt compile Я хотел бы видеть:

...log...
This is my before test text
...compile log...
This is my after test text

Так что мне нужно иметь:

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")
     }
  }
}

Так что я думаю, что мне нужны такие вещи, как dependsOn и in, но я не уверен, как их настроить.

1 Ответ

0 голосов
/ 15 ноября 2018

Невозможно настроить для конкретной задачи запуск после данной задачи, потому что это не так, как работает модель зависимостей задачи - когда вы задаете задачу, ее зависимости и сама она будет выполнена, но нет способа определить зависимость "после". Однако вы можете смоделировать это с помощью динамических задач.

Чтобы запустить одну задачу перед другой, вы можете использовать dependsOn:

compile in Compile := (compile in Compile).dependsOn(myBeforeTask).value

Это устанавливает зависимость между двумя задачами, что гарантирует запуск myBeforeTask до compile in Compile.


Обратите внимание, что существует более общий способ запуска нескольких задач одна за другой:

aggregateTask := Def.sequential(task1, task2, task3, task4).value

Def.sequential опирается на механизм динамических задач, который устанавливает зависимости между задачами во время выполнения. Однако существуют некоторые ограничения для этого механизма, в частности, вы не можете ссылаться на задачу, определенную в списке задач для выполнения, поэтому вы не можете использовать Def.sequential для дополнения существующих задач:

compile in Compile := Def.sequential(myBeforeTask, compile in Compile).value

Это определение не будет выполнено во время выполнения со странным сообщением об ошибке, которое в основном означает, что у вас есть цикл в графике зависимостей задач. Однако для некоторых случаев использования это чрезвычайно полезно.


Чтобы выполнить одну задачу после другой, вам придется прибегнуть к определению динамической зависимости задачи с помощью Def.taskDyn:

compile in Compile := Def.taskDyn {
  val result = (compile in Compile).value
  Def.task {
    val _ = myAfterTask.value
    result
  }
}.value

Def.taskDyn принимает блок, который должен возвращать Def.Initialize[Task[T]], который будет использоваться для создания экземпляра задачи, которая будет запущена позже, после завершения основной части Def.taskDyn. Это позволяет динамически вычислять задачи и устанавливать зависимости между задачами во время выполнения. Однако, как я сказал выше, это может привести к очень странным ошибкам, возникающим во время выполнения, которые обычно вызваны циклами в графе зависимостей.

Таким образом, полный пример с заданиями «до» и «после» будет выглядеть так:

compile in Compile := Def.taskDyn {
  val result = (compile in Compile).value
  Def.task {
    val _ = myAfterTask.value
    result
  }
}.dependsOn(myBeforeTask).value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...