Объедините несколько задач sbt в одну

Я немного запутался в документации Scala/SBT по созданию задач Scala. В настоящее время я могу запустить следующее из командной строки:

sbt ";set target := file(\"$PWD/package/deb-upstart\"); set serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.Upstart; debian:packageBin; set target := file(\"$PWD/package/deb-systemv\"); set serverLoading in Debian := com.typesafe.sbt.packager.archtypes.ServerLoader.SystemV; debian:packageBin; set target := file(\"$PWD/package/rpm-systemd\"); rpm:packageBin"

Это сбрасывает мою цель каждый раз в другой каталог (deb-upstart, deb-systemv и rpm-systemd) и запускает задачу sbt-native-package для каждой из этих настроек. (Да, я понимаю, что компилирую его три раза, но sbt-native-packager, похоже, не имеет настройки для каталога артефактов)

Это отлично работает из приглашения bash, но я пытался поставить ту же цель в jenkins (заменив $PWD на $WORKSPACE), и я не могу правильно экранировать цитату. Я подумал, что может быть проще просто иметь задачу в build.sbt или project/Build.scala, которая запускает все три из этих задач, каждый раз меняя целевую переменную (и заменяя $PWD или $TARGET полным путем базового каталога).

Я пробовал следующее:

 lazy val packageAll = taskKey[Unit]("Creates deb-upstart, deb-systenv and rpm-systemd packages")

packageAll := {
  target := baseDirectory.value / "package" / "deb-upstart"

  serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.Upstart

  (packageBin in Debian).value

  target := baseDirectory.value / "package" / "deb-systemv"

  serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.SystemV

  (packageBin in Debian).value

  target := baseDirectory.value / "package" / "rpm-systemd"

  (packageBin in Rpm).value

}

Но проблема в том, что .value заставляет задачи оцениваться еще до того, как моя задача будет запущена, поэтому они не получают новую целевую настройку (как указано в этом другом вопросе: Как я могу вызвать другую задачу из моей задачи SBT?)


person djsumdog    schedule 15.01.2015    source источник
comment
Я не уверен, но пытались ли вы выделить каждый пользовательский шаг packageBin в пользовательскую задачу, а затем объединить их с packageAll? Выходные каталоги, если они были изменены только один раз, также могут быть установлены с помощью target in Rpm или target in Debian.   -  person Muki    schedule 20.01.2015
comment
@Muki Хотел бы я просто target in [Setting], но если вы посмотрите внимательно, вы увидите, что я дважды меняю цель для Debian, один раз для Upstart ServerLoader и один раз для SystemV ServerLoader. Как мне извлечь каждый packageBin в пользовательскую задачу?   -  person djsumdog    schedule 20.01.2015


Ответы (1)


Итак, я понял это для вас :) Как вы уже упоминали, объединение нескольких задач в одну, где некоторые задачи зависят от одной и той же настройки, не работает должным образом.

Вместо этого мы делаем следующее

  1. Создайте задачу для каждого из наших пользовательских шагов, например. упаковка Debian для выскочки
  2. Определите псевдоним, который выполняет эти команды по порядку.

Определить задачи

lazy val packageDebianUpstart = taskKey[File]("creates deb-upstart package")
lazy val packageDebianSystemV = taskKey[File]("creates deb-systenv package")
lazy val packageRpmSystemD = taskKey[File]("creates rpm-systenv package")

Пример реализации задачи

Реализация довольно проста и одинакова для каждой из задач.

// don't forget this
import com.typesafe.sbt.packager.archetypes._

packageDebianUpstart := {
  // define where you want to put your stuff
  val output = baseDirectory.value / "package" / "deb-upstart"

  // run task
  val debianFile = (packageBin in Debian).value

  // place it where  you want
  IO.move(debianFile, output)
  output
}

Определить псевдоним

А теперь скомпонуйте эти задачи в один алиас с

addCommandAlias("packageAll", "; clean " + 
                          "; set serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.SystemV" +
                          "; packageDebianSystemV " +
                          "; clean " + 
                          "; set serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.Upstart" +
                          "; packageDebianUpstart " + 
                          "; packageRpmSystemD")

Полный код можно посмотреть здесь.

Обновлять

Установка SystemLoader внутри псевдонима кажется правильным способом решить эту проблему. К сожалению, между каждой сборкой для одного и того же выходного формата необходима очистка.

person Muki    schedule 23.01.2015
comment
Это решение не работает. Он переименовывает пакет в deb-upstart вместо того, чтобы помещать его в каталог (я пытался добавить scalax.file.Path(output).createDirectory() сразу после val output, но он по-прежнему переименовывает пакеты, а не размещает их в своем собственном каталоге). Кроме того, если вы запустите dpkg-deb -c deb-systemv, вы увидите, что это на самом деле версия upstart. .value запускает эти задачи перед пользовательской задачей. Единственный способ сделать это с помощью команды. Я пытался работать над одним; может выдать запрос на вытягивание, если я смогу понять это. - person djsumdog; 25.01.2015
comment
Я обновил пример. Настройка внутри задач видимо обрабатывается sbt не корректно или делается по другому. Настройка извне через псевдоним работает. Каталог создан правильно для меня и перемещает файлы, как описано. IO.move(package, outputfolder). - person Muki; 25.01.2015