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

Plugins 在SBT中定义自定义源文件依赖项,plugins,sbt,Plugins,Sbt,当另一个非scala文件B更改时,如何使SBT重新编译某个文件A 我定义了一个宏: printMacro("path/to/file") 它从“path/to/file”指示的文件创建字符串文本 每当该文件发生更改时,需要重新编译使用该宏的文件以反映这些更改。我可以使用watchSources来监视该文件的更改,并在更改时重新编译项目,但由于使用了增量编译器,这种重新编译实际上什么都不做 我几乎肯定需要编写一个插件来实现这一点,但我找不到sbt中的哪些挂钩可以让我编写这样的插件 编辑:重新编译

当另一个非scala文件B更改时,如何使SBT重新编译某个文件A

我定义了一个宏:

printMacro("path/to/file")
它从“path/to/file”指示的文件创建字符串文本

每当该文件发生更改时,需要重新编译使用该宏的文件以反映这些更改。我可以使用
watchSources
来监视该文件的更改,并在更改时重新编译项目,但由于使用了增量编译器,这种重新编译实际上什么都不做

我几乎肯定需要编写一个插件来实现这一点,但我找不到sbt中的哪些挂钩可以让我编写这样的插件


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

这个基于的解决方案怎么样

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

  • cachedbaseddirectory
    -它将保存缓存元数据的位置
  • inStyle
    -决定
  • 操作
    -在观察到的文件更改时调用该操作
该函数返回另一个函数,该函数接受一组受监视的文件

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
将使项目重新编译


最后,我们使原始的
编译
依赖于我们新创建的任务。

这与我现有的方法非常相似。问题是,只要监控的文件发生更改,它就会清除整个项目,这可能会导致大型项目的长时间延迟。我试图使用它的一个这样的项目实际上需要几分钟才能从头编译。这就是我寻找更有针对性的方法的原因。