Плагин SBT: Как вывести список файлов путем инкрементальной перекомпиляции
Я пишу плагин для SBT, который требует список файлов классов, сгенерированных при последнем запуске компилятора Scala.
Этот список файлов классов затем передается в программу, которая выполняет некоторые преобразования байт-кода. Поскольку этот процесс преобразования может быть медленным, мне нужны только файлы классов, записанные при последнем запуске компилятора Scala (то есть те, которые там были изменены), а не все файлы классов в выходном каталоге.
Как я могу получить список файлов, сгенерированных последним compile
задача?
1 ответ
Я думаю, что вы не можете получить эту информацию непосредственно от Analysis
объект, возвращаемый compile
задача.
Однако, что вы можете сделать, это проверить analysis.relations.allProducts
для изменений. Если какой-либо из файлов был изменен, вы можете выполнить свою задачу, которая выполняет преобразования байт-кода.
Вы можете использовать модифицированную версию FileFunction.cached для проверки изменений.
def cached(cacheBaseDirectory: File, inStyle: FilesInfo.Style)(action: Set[File] => Unit): Set[File] => Unit = {
import Path._
lazy val inCache = Difference.inputs(cacheBaseDirectory / "in-cache", inStyle)
inputs => {
inCache(inputs) { inReport =>
if(!inReport.modified.isEmpty) action(inReport.modified)
}
}
}
Функция принимает следующие параметры:
cacheBaseDirectory
- расположение кешаinStyle
- описание того, как изменения должны быть обнаружены (см. sbt.FilesInfo для возможных вариантов)action
- функция запускается, когда файлы были изменены. Функция принимает список измененных файлов в качестве аргумента.
Функция возвращает другую функцию, которая запускается только в том случае, если набор файлов, переданных ей в качестве аргумента, изменен.
пример
val transformBytecode = taskKey[Unit]("Transforms bytecode of modified files")
def cached(cacheBaseDirectory: File, inStyle: FilesInfo.Style)(action: Set[File] => Unit): Set[File] => Unit = {
import Path._
lazy val inCache = Difference.inputs(cacheBaseDirectory / "in-cache", inStyle)
inputs => {
inCache(inputs) { inReport =>
if(!inReport.modified.isEmpty) action(inReport.modified)
}
}
}
transformBytecode <<= Def.task {
val analysis = (compile in Compile).value
val cachedFunction = cached(streams.value.cacheDirectory / "transform-bytecode", FilesInfo.lastModified) { modified =>
// here you want to run the bytecode transformations on `modified` files
println(s"Modified files $modified")
}
cachedFunction(analysis.relations.allProducts.toSet)
}.triggeredBy(compile in Compile)