1. 触发执行

触发执行 

sbt 提供了监视特定任务的输入文件并在这些文件发生更改时重复该任务的能力。

下面描述了一些示例用法

编译 

一个常见的用例是持续编译。以下命令将使 sbt 监视 Test 和 Compile(默认)配置中的源代码更改,并重新运行编译命令。

> ~ Test / compile

> ~ compile

请注意,由于 Test / compile 依赖于 Compile / compile,因此主源目录中的源代码更改将触发测试源代码的重新编译。

测试 

触发执行通常用于测试驱动开发 (TDD) 风格的开发。以下命令将监视构建的主源和测试源中的更改,并且仅重新运行引用自上次测试运行以来重新编译的类的测试。

> ~ testQuick

也可以仅在测试的依赖项发生更改时重新运行特定测试。

> ~ testQuick foo.BarTest

即使测试不依赖于任何更新的源文件,也可以在检测到源代码更改时始终重新运行测试。

> ~ testOnly foo.BarTest

要运行项目中的所有测试,无论何时发生任何源代码更改,请使用

> ~test

运行多个命令 

sbt 支持监视多个用分号分隔的命令。例如,以下命令将监视源文件更改并运行 cleantest

> ~ clean; test

构建源代码 

如果构建配置为通过设置 Global / onChangedBuildSource := ReloadOnSourceChanges 在构建源代码发生更改时自动重新加载,那么 sbt 将监视构建源代码(即 project 目录中的 *.sbt*.{java,scala} 文件)。当检测到构建源代码更改时,构建将重新加载,并且 sbt 将在重新加载完成后重新进入触发执行模式。

以下代码段可以作为 全局设置 添加到 ~/.sbt/1.0/config.sbt 中,以在所有 sbt 1.3+ 构建中启用 ReloadOnSourceChanges,而不会破坏早期版本

Def.settings {
  try {
    val value = Class.forName("sbt.nio.Keys$ReloadOnSourceChanges$").getDeclaredField("MODULE$").get(null)
    val clazz = Class.forName("sbt.nio.Keys$WatchBuildSourceOption")
    val manifest = new scala.reflect.Manifest[AnyRef]{ def runtimeClass = clazz }
    Seq(
      Global / SettingKey[AnyRef]("onChangedBuildSource")(manifest, sbt.util.NoJsonWriter()) := value
    )
  } catch {
    case e: Throwable =>
      Nil
  }
}

清除屏幕 

sbt 可以在评估任务之前或在触发事件之后清除控制台屏幕。要配置 sbt 在事件触发后清除屏幕,请添加

ThisBuild / watchTriggeredMessage := Watch.clearScreenOnTrigger

到构建设置中。要在运行任务之前清除屏幕,请添加

ThisBuild  / watchBeforeCommand := Watch.clearScreen

到构建设置中。

配置 

触发执行的行为可以通过许多设置进行配置。

  • watchTriggers: Seq[Glob] 添加了对应该触发任务评估但任务不直接依赖的文件的搜索查询。例如,如果项目 build.sbt 文件包含 foo / watchTriggers += baseDirectory.value.toGlob / "*.txt",那么对以 txt 扩展名结尾的文件的任何修改都将导致 foo 命令在触发执行模式下触发。
  • watchTriggeredMessage: (Int, Path, Seq[String]) => Option[String] 设置文件修改触发新构建时显示的消息。其输入参数是当前监视迭代次数、触发构建的文件以及要运行的命令。默认情况下,它会打印一条消息,指示触发构建的文件以及将要运行的命令。当函数返回 None 时,不会打印任何消息。要在打印消息之前清除屏幕,只需在任务定义中添加 Watch.clearScreen() 即可。这将确保在清除屏幕后打印消息(如果有定义)。
  • watchInputOptions: Seq[Watch.InputOption] 允许构建覆盖默认监视选项。例如,要添加通过键入“l”键重新加载构建的功能,请将 ThisBuild / watchInputOptions += Watch.InputOption('l', "reload", Watch.Reload) 添加到 build.sbt 文件中。当使用默认的 watchStartMessage 时,这也会将该选项添加到“?”选项显示的列表中。
  • watchBeforeCommand: () => Unit 提供了一个在评估任务之前运行的回调。它可用于通过将 ThisBuild / watchBeforeCommand := Watch.clearScreen 添加到项目 build.sbt 文件中来清除控制台屏幕。默认情况下,它什么也不做。
  • watchLogLevel 设置文件监视系统的日志记录级别。如果在修改源文件或意外触发时未评估触发执行,或者由于不应该监视的文件的修改而意外触发,这将很有用。
  • watchInputParser: Parser[Watch.Action] 更改监视器如何处理输入事件。例如,设置 watchInputParser := 'l' ^^^ Watch.Reload | '\r' ^^^ new Watch.Run("") 将使键入“l”键重新加载构建,键入换行符将返回到 shell。默认情况下,这会从 watchInputOptions 自动推导而来。
  • watchStartMessage: (Int, ProjectRef, Seq[String]) => Option[String] 设置监视进程在等待文件或输入事件时打印的横幅。输入是迭代次数、当前项目以及要运行的命令。默认消息包括用于终止监视或显示所有可用选项的说明。只有当 watchOnIteration 记录 watchStartMessage 的结果时,才会显示此横幅。
  • watchOnIteration: (Int, ProjectRef, Seq[String]) => Watch.Action 是在等待源代码或输入事件之前评估的函数。它可用于在达到特定迭代次数时提前终止监视。默认情况下,它只是记录 watchStartMessage 的结果。
  • watchForceTriggerOnAnyChange: Boolean 配置源文件的内容是否必须更改才能触发构建。默认值为 false。
  • watchPersistFileStamps: Boolean 切换 sbt 是否会持久化跨多个任务评估运行计算的源文件的哈希值。这可以提高具有许多源文件的项目的性能。由于文件哈希被缓存,因此如果许多源文件正在同时修改,则评估的任务可能会读取无效的哈希值。默认值为 false。
  • watchAntiEntropy: FiniteDuration 控制在同一个文件先前触发构建后,构建重新触发之前必须经过的时间。这旨在防止在短时间内多次修改文件时可能发生的错误构建。默认值为 500 毫秒。