У меня есть проект sbt, который включает генерацию кода.
Часть build.sbt:
lazy val generator = (project in file("generator")).
settings(mainClass := Some("com.example.Generator"))
lazy val generate = (project in file("generate")).
dependsOn(generator).
settings(runGeneration)
def runGeneration: SettingsDefinition = sourceGenerators in Compile += Def.taskDyn {
val cachedFun = FileFunction.cached(
streams.value.cacheDirectory / "generation"
) { (in: Set[File]) =>
val dir = (sourceManaged in Compile).value
(generator / run in Compile).toTask(" " + dir.getAbsolutePath).value
collectFiles(dir)
}
val dependentFiles = ((generator / fullClasspath in Compile) map { cp => cp.files }).taskValue.value
val genFiles = cachedFun(dependenctFiles).toSeq
Def.task {
genFiles
}
}.taskValue
Кажется, что это работает и генерирует файлы только при изменении зависимости.Тем не менее, я ожидаю иметь несколько генераторов.Вместо того, чтобы скопировать код, я попытался передать ему проект generator
:
lazy val generate = (project in file("generate")).
dependsOn(generator).
settings(runGeneration(generator))
def runGeneration(p: project): SettingsDefinition =
<same as before but with p instead of generator>
Это приводит к ошибке синтаксического анализа файла сборки:
build.sbt:155: error: Illegal dynamic reference: File
val dependentFiles = ((p / fullClasspath in Compile) map { cp => cp.files }).taskValue.value
^
[error] sbt.compiler.EvalException: Type error in expression
[error] sbt.compiler.EvalException: Type error in expression
Я предполагаюПроблема в том, что он не может выяснить во время компиляции, если есть цикл зависимости, поэтому он выдает ошибку.
Есть ли способ заставить это работать?Существует ли совершенно другая конструкция, которая позволяет мне узнать, даст ли выполнение generator
другой результат?