#scala #sbt #sbt-assembly
#scala #sbt #sbt-assembly
Вопрос:
Я не могу упаковать свои тестовые зависимости в мою тестовую сборку jar. Вот выдержка из моего build.sbt
:
...
name := "project"
scalaVersion := "2.10.6"
assemblyOption in (Compile, assembly) := (assemblyOption in (Compile, assembly)).value.copy(includeScala = false)
fork in Test := true
parallelExecution in IntegrationTest := false
lazy val root = project.in(file(".")).configs(IntegrationTest.extend(Test)).settings(Defaults.itSettings: _ *)
Project.inConfig(Test)(baseAssemblySettings)
test in (Test, assembly) := {}
assemblyOption in (Test, assembly) := (assemblyOption in (Test, assembly)).value.copy(includeScala = false, includeDependency = true)
assemblyJarName in (Test, assembly) := s"${name.value}-test.jar"
fullClasspath in (Test, assembly) := {
val cp = (fullClasspath in Test).value
cp.filter{ file => (file.data.name contains "classes") || (file.data.name contains "test-classes")} (fullClasspath in Runtime).value
}
libraryDependencies = Seq(
...
"com.typesafe.play" %% "play-json" % "2.3.10" % "test" excludeAll ExclusionRule(organization = "joda-time"),
...
)
...
Когда я собираю свой fat jar с помощью sbt test:assembly
, is создает fat jar project-test.jar
, но play-json
зависимости не упаковываются в:
$ jar tf /path/to/project-test.jar | grep play
$
Однако, если я удалю "test"
конфигурацию из play-json
dep (т. Е. "com.typesafe.play" %% "play-json" % "2.3.10" excludeAll ExclusionRule(organization = "joda-time")
), я увижу, что она включена:
$ jar tf /path/to/project-test.jar | grep play
...
play/libs/Json.class
...
$
Я делаю что-то неправильно и / или чего-то не хватает? Моя цель здесь — включить play-json
библиотеку ТОЛЬКО в test:assembly
jar, а НЕ в assembly
jar
Ответ №1:
Я пропустил важную часть в оригинальном build.sbt
отрывке, который я опубликовал выше, которая оказалась причиной ошибки:
fullClasspath in (Test, assembly) := {
val cp = (fullClasspath in Test).value
cp.filter{ file => (file.data.name contains "classes") || (file.data.name contains "test-classes")} (fullClasspath in Runtime).value
}
Этот блок кода, по сути, отфильтровывал deps из пути к тестовому классу. Мы включаем это, чтобы избежать болезненных конфликтов слияния. Я исправил это, добавив логику для включения play-json
dep, которая была необходима:
fullClasspath in (Test, assembly) := {
val cp = (fullClasspath in Test).value
cp.filter{ file =>
(file.data.name contains "classes") ||
(file.data.name contains "test-classes") ||
// sorta hacky
(file.data.name contains "play")
} (fullClasspath in Runtime).value
}