1

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

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

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

4

1 回答 1

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)
于 2014-05-26T18:47:13.040 回答