Как генерировать ресурсы для задачи?

#sbt #sbt-assembly

#sbt #sbt-сборка

Вопрос:

Для моей Runtime конфигурации я могу определить дополнительные resourceGenerator ресурсы следующим образом:

 resourceGenerators in Runtime < = myResourceGeneratingTask
  

Для assembly задачи это не работает:

 resourceGenerators in assembly < = myResourceGeneratingTask
  

Сообщение об ошибке:

 Reference to undefined setting:

  *:assembly::resourceGenerators from *:assembly::resourceGenerators (...build.sbt:20)
  

Когда я меняю оператор ‘append’ < = на присваивание <<= , это больше не вызывает никаких ошибок, но мой генератор ресурсов не вызывается.

Ответ №1:

Обратите внимание, что я использую sbt 0.13.5. Он также работает с Typesafe Activator 1.2.3 (поскольку он основан на sbt 0.13.5).

assembly является ли задача не конфигурацией и не предлагает resourceGenerators настройки и, следовательно, ошибка — undefined setting .

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

 resourceGenerators in (Runtime, assembly)  = myResourceGeneratingTask.taskValue
  

Обратите внимание, что я использую комбинацию = и taskValue , которая является предпочтительным подходом в 0.13. Я также извлек метод def makeSomeSources , чтобы при необходимости использовать его повторно в других вариантах использования. Смотрите раздел «Генерация файлов» в официальной документации sbt:

Поскольку мы хотим добавить задачу, а не значение после ее выполнения, мы используем taskValue вместо обычного значения. Область действия должна определяться в зависимости от того, являются ли генерируемые файлы основными ( Compile ) или тестовыми ( Test ) ресурсами.

В вашем случае это для assembly задачи в Runtime конфигурации.

build.sbt я использовал для справки:

 import AssemblyKeys._

assemblySettings

def makeSomeSources(f: File): Seq[File] = {
  val content = "Hello"
  IO.write(f, content)
  Seq(f)
}

lazy val myResGenT = taskKey[Seq[File]]("My personal resgen")

myResGenT := {
  val log = streams.value.log
  val f = (resourceManaged in Compile).value / "resgen.xml"
  val fs: Seq[File] = makeSomeSources(f)
  log.info(s"Generating file(s): $fs")
  fs
}

resourceGenerators in Compile  = myResGenT.taskValue

resourceGenerators in Runtime  = myResGenT.taskValue

resourceGenerators in (Runtime, assembly)  = myResGenT.taskValue
  

Выполнение runtime:assembly дает мне следующий результат:

 > runtime:assembly
[info] Generating file(s): List(C:devsandboxresourceGeneratorstargetscala-2.10resource_managedmainresgen.xml)
[info] Including: scala-library.jar
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INFMANIFEST.MF' with strategy 'discard'
[warn] Strategy 'discard' was applied to a file
[info] SHA-1: 875d4b95f38dc85d14e53bdcd10e442520aeeefd
[info] Packaging C:devsandboxresourceGeneratorstargetscala-2.10resourcegenerators-assembly-0.1-SNAPSHOT.jar ...
[info] Done packaging.
  

Комментарии:

1. Мне пришлось заменить = .taskValue вернемся к < = , но тогда действительно ваш пример работает как шарм, спасибо! Это помогло мне найти решение для моего реального проекта (который сложнее из-за использования подпроектов) — не уверен, что это сделало бы полезный вопрос stackoverflow.

2. Причиной этого является используемая вами версия sbt. Попробуйте последнюю версию 0.13.5, и вы не будете оглядываться назад. Спасибо, что приняли ответ.

3. Действительно, обновление с 0.13.0 до 0.13.5 заставило ваш пример работать, еще раз спасибо!