SBT插件:如何列出通过增量重新编译输出的文件

时间:2014-05-26 15:04:54

标签: scala plugins sbt incremental-compiler

我正在为SBT编写一个插件,它需要上次运行Scala编译器生成的类文件列表。

然后将此类文件列表传递到执行某些字节码转换的程序中。由于这个转换过程可能很慢,我只想要上次运行Scala编译器(即修改过的那些)编写的类文件,而不是输出目录中的所有类文件。

如何获取compile任务最后生成的文件列表?

1 个答案:

答案 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)