Фильтрация ресурсов в SBT

Я пытаюсь настроить SBT для компиляции существующего проекта, который не использует структуру каталога maven. Я использую полную конфигурацию и установил параметры javaSource и resourceDirectory следующим образом:

def settings = Defaults.defaultSettings ++ Seq(
    resourceDirectory in Compile <<= baseDirectory( _ / "java" ),
    javaSource in Compile <<= baseDirectory( _ / "java" )
)

Теперь я хочу, чтобы иметь возможность фильтровать ресурсы, которые мы включаем в артефакт jar, как мы в настоящее время делаем с ant, плюс исключить .java файлы, поскольку наши ресурсы смешиваются с исходным кодом. Например:

<fileset dir="java" includes="**/*.txt, **/*.csv" excludes="**/*.java" />

Есть ли способ сделать это?

Ответ 1

Используйте defaultExcludes для задачи unmanagedResources и, возможно, конфигурацию. Например, этот параметр исключает файлы .java из основных ресурсов:

defaultExcludes in Compile in unmanagedResources := "*.java"

in Compile ограничивает этот параметр применимым только к основным ресурсам. Используя in Test вместо этого, он будет применяться только к тестовым ресурсам. Отключив конфигурацию (то есть no in Compile или in Test), этот параметр будет применяться как к основным, так и к тестовым ресурсам.

in unmanagedResources применяет эти исключения только для ресурсов. Например, для применения исключений к источникам будет in unmanagedSources. Причина неуправляемой части заключается в том, чтобы подчеркнуть, что они применяются только к неуправляемым (или отредактированным вручную) источникам.

Клавиша defaultExcludes имеет тип sbt.FileFilter, поэтому значение параметра должно быть такого типа. В приведенном выше примере "*.java" неявно преобразуется в FileFilter. * интерпретируется как подстановочный знак, поэтому фильтр принимает файлы с именем, которое заканчивается на ".java". Чтобы объединить фильтры, вы используете || и &&. Например, если необходимо также исключить файлы .scala, аргументом := будет:

"*.java" || "*.scala"

В исходном наборе файлов Ant фильтры include и exclude выбирают взаимоисключающие наборы файлов, поэтому требуется только один.

Также можно напрямую построить Seq[File] для unmanagedResources. Например:

unmanagedResources in Compile <<=
  unmanagedResourceDirectories in Compile map { (dirs: Seq[File]) =>
    ( dirs ** ("*.txt" || "*.csv" -- "*.java") ).get
  }

Метод ** выбирает все потомки, которые соответствуют аргументу FileFilter. Вы можете проверить, что файлы выбраны так, как вы ожидаете, запустив show unmanaged-resources.