我正在为SBT编写一个插件,它需要Scala编译器最后运行时生成的类文件列表。
然后将这个类文件列表传递给执行一些字节码转换的程序。由于这个转换过程可能很慢,所以我只需要Scala编译器最后一次运行时编写的类文件(即那些被修改过的类文件),而不是输出目录中的所有类文件。如何获取compile
任务最后生成的文件列表?
我认为您无法直接从compile
任务返回的Analysis
对象中获得此信息。
然而,你能做的是检查analysis.relations.allProducts
是否有变化。如果任何文件被修改,您可以执行您的任务,该任务执行字节码转换。
你可以使用一个修改过的FileFunction。已缓存,用于检查更改
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. 6)。 -
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)