我正在为SBT编写一个插件,它需要上次运行Scala编译器生成的类文件列表。
然后将此类文件列表传递到执行某些字节码转换的程序中。由于这个转换过程可能很慢,我只想要上次运行Scala编译器(即修改过的那些)编写的类文件,而不是输出目录中的所有类文件。
如何获取compile
任务最后生成的文件列表?
答案 0 :(得分:3)
我认为您无法直接从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)