在SBT中定义自定义源文件依赖项

时间:2014-05-19 14:40:23

标签: plugins sbt

如果另一个非scala文件B发生变化,我怎样才能让SBT重新编译某个文件?

我定义了一个宏:

printMacro("path/to/file")

从" path / to / file"指示的文件中创建一个字符串文字。

每当该文件发生更改时,都需要重新编译使用该宏的文件以反映这些更改。我可以使用watchSources监视该文件以进行更改,并在项目执行时重新编译该项目,但由于增量编译器,此重新编译实际上并没有做任何事情。

我几乎肯定需要编写一个插件才能完成此操作,但是我找不到哪个钩子进入sbt会让我编写这样的插件。

编辑:重新编译整个项目是不可取的,因为可能有多个跟踪文件,项目本身可能非常大。

1 个答案:

答案 0 :(得分:0)

此解决方案如何基于FileFunction.cached

基本上定义一个函数,它需要:

  • cachedBaseDirectory - 它将保留缓存元数据的位置
  • inStyle - 决定how it checks for changes
  • action - 在观察文件发生变化时调用

该函数返回另一个函数,该函数接受一组受监视的文件。

def cached(cacheBaseDirectory: File, inStyle: FilesInfo.Style)(action: => Unit): Set[File] => Unit = {
  import Path._
  lazy val inCache = Difference.inputs(cacheBaseDirectory / "in-cache", inStyle)
  inputs => {
    inCache(inputs) { inReport =>
      if(!inReport.modified.isEmpty) action
    }
  }
}

这是您在build.sbt

中使用它的方法
val recompileWhenFileChanges = taskKey[Unit]("Recompiles the project when a file changes")

recompileWhenFileChanges := {
  val base = baseDirectory.value
  val mySpecialFile = baseDirectory.value / "path" / "to" / "file" / "test.txt"
  val cache = cacheDirectory.value / "my_cache_dir"
  val cachedFunction = cached(cache, FilesInfo.lastModified)(IO.delete((classDirectory in Compile).value))
  cachedFunction(mySpecialFile.get.toSet)
} 

compile in Compile := ((compile in Compile) dependsOn recompileWhenFileChanges).value

仅当文件发生更改时,任务才会删除classDirectory。删除classDirectory会使项目重新编译。

最后,我们让原始compile依赖于我们新创建的任务。