Запускать пользовательское задание автоматически до / после стандартного задания

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

Поэтому я хочу определить пользовательскую задачу (скажем, prepare-app) и вставить ее в дерево зависимостей существующих задач (скажем, package-bin), чтобы каждый раз, когда кто-то вызывал package-bin, мои пользовательские задачи выполнялись прямо перед ним.

Я пытался сделать это

  def mySettings = {
    inConfig(Compile)(Seq(prepareAppTask <<= packageBin in Compile map { (pkg: File) =>
      // fiddle with the /target folder before package-bin makes it into a jar
    })) ++
    Seq(name := "my project", version := "1.0")
  }

  lazy val prepareAppTask = TaskKey[Unit]("prepare-app")

но он не выполняется автоматически package-bin прямо перед упаковкой вывода компиляции в jar. Итак, как мне изменить приведенный выше код для запуска в нужное время?

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

1 ответ

Решение

Расширение существующей задачи документировано в документации SBT для задач (см. Раздел " Изменение существующей задачи").

Что-то вроде этого:

compile in Compile <<= (compile in Compile) map { _ => 
  // what you want to happen after compile goes here 
}

Собственно, есть и другой способ - определить свою задачу, чтобы зависеть от компиляции

prepareAppTask := (whatever you want to do) dependsOn compile

и затем измените packageBin, чтобы зависеть от этого:

packageBin <<= packageBin dependsOn prepareAppTask

(все вышеперечисленное не проверено, но общая тяга должна работать, я надеюсь).

Как обновление для предыдущего ответа @Paul Butcher, это может быть сделано несколько иначе в версиях SBT 1.x, так как <<== больше не поддерживается. Я взял пример примера задачи, выполняемой перед компиляцией, которую я использую в одном из моих проектов:

lazy val wsdlImport = TaskKey[Unit]("wsdlImport", "Generates Java classes from WSDL")

wsdlImport := {
  import sys.process._
  "./wsdl/bin/wsdl_import.sh" !
  // or do whatever stuff you need
}

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

Это очень похоже на то, как это было сделано до 1.x.

Кроме того, есть официальный способ, предложенный официальными документами SBT, который представляет собой набор задач (а не иерархию зависимостей). Взяв тот же пример, что и выше:

(compile in Compile) := {
  val w = wsdlImport.value
  val c = (compile in Compile).value
  // you can add more tasks to composition or perform some actions with them
  c
}

В некоторых случаях кажется, что нужно дать больше гибкости, хотя первый пример выглядит немного аккуратнее, как для меня.

Протестировано на SBT 1.2.3, но должно работать и с другими 1.x.

Другие вопросы по тегам