Создавая мой проект на Scala с помощью sbt, я хочу задание, которое будет выполнено до фактической компиляции Scala и сгенерирует файл Version.scala
с информацией о версии проекта. Вот задача, с которой я столкнулся:
lazy val generateVersionTask = Def.task {
// Generate contents of Version.scala
val contents = s"""package io.kaitai.struct
|
|object Version {
| val name = "${name.value}"
| val version = "${version.value}"
|}
|""".stripMargin
// Update Version.scala file, if needed
val file = (sourceManaged in Compile).value / "version" / "Version.scala"
println(s"Version file generated: $file")
IO.write(file, contents)
Seq(file)
}
Эта задача, похоже, работает, но проблема в том, как ее подключить, учитывая, что это кросс-проект, нацеленный на Scala / JVM, Scala / JS и т. Д.
Вот так выглядел build.sbt
, прежде чем я начал его трогать
lazy val root = project.in(file(".")).
aggregate(fooJS, fooJVM).
settings(
publish := {},
publishLocal := {}
)
lazy val foo = crossProject.in(file(".")).
settings(
name := "foo",
version := sys.env.getOrElse("CI_VERSION", "0.1"),
// ...
).
jvmSettings(/* JVM-specific settings */).
jsSettings(/* JS-specific settings */)
lazy val fooJVM = foo.jvm
lazy val fooJS = foo.js
и в файловой системе у меня есть:
- shared / - кросс-платформенный код, общий для сборок JS / JVM
- jvm / - JVM-специфичный код
- js / - JS-специфический код
Лучшее, что я придумал, это добавление этой задачи в foo
crossProject:
lazy val foo = crossProject.in(file(".")).
settings(
name := "foo",
version := sys.env.getOrElse("CI_VERSION", "0.1"),
sourceGenerators in Compile += generateVersionTask.taskValue, // <== !
// ...
).
jvmSettings(/* JVM-specific settings */).
jsSettings(/* JS-specific settings */)
Это работает, но очень неловко, не совсем совместимо с «разделяемой» кодовой базой. Он генерирует 2 отдельных файла Version.scala для JS и JVM:
sbt:root> compile
Version file generated: /foo/js/target/scala-2.12/src_managed/main/version/Version.scala
Version file generated: /foo/jvm/target/scala-2.12/src_managed/main/version/Version.scala
Естественно, невозможно получить доступ к содержимому этих файлов из shared
, и именно здесь я хочу получить к нему доступ.
Пока что я пришел с очень небрежным обходным путем:
- В одиночном объекте в общем
- в основных точках входа JVM и JS самое первое, что я делаю, это назначаю эту переменную для соответствия константам, определенным в
Version.scala
Кроме того, я попробовал тот же трюк с плагином sbt-buildinfo - результат точно такой же, он генерировал для каждой платформы BuildInfo.scala
, который я не могу использовать напрямую из общих источников .
Есть ли лучшие решения?