如何在另一个任务失败后执行任务或命令
How to execute a task or command after another task even if it failed
我在 sbt 中有一个相当长的 运行 任务,我希望在它完成后得到声音通知,即使失败了也能收到通知。我以这种粗鲁的方式部分地到达了那里:
lazy val ding = taskKey[Unit]("plays a ding sound")
ding := {
Seq("play", "-q", "/…/SmallGlockA.wav").run
}
我这样调用上述任务:
sbt> ;test;ding
虽然在任务成功时效果很好,但如果任务失败,它当然不会播放声音,考虑到它是测试,这很可能。
有什么办法可以解决这个问题吗?它不必非常漂亮或超级健壮——这不会被提交,这对我来说只是本地的事情。
我提出的解决方案是为 sbt 创建一个 AutoPlugin
来满足您的需求。
在名为 DingPlugin.scala
的 project
文件夹中创建一个包含以下内容的新文件
import sbt.Keys._
import sbt.PluginTrigger.AllRequirements
import sbt._
object DingPlugin extends AutoPlugin {
private def wavPath = "/path/to/wav"
private def playSound(wav: String) = ???
override def trigger = AllRequirements
override def projectSettings: Seq[Def.Setting[_]] = Seq(
Test / test := (Test / test).andFinally(playSound(wavPath)).value
)
}
重点是方法andFinally
that
defines a new task that runs the original task and evaluates a side effect regardless of whether the original task succeeded. The result of the task is the result of the original task
playSound
的实现是从这个question导出的,代码如下
private def playSound(wav: String): Unit = {
import java.io.BufferedInputStream
import java.io.FileInputStream
import javax.sound.sampled.AudioSystem
val clip = AudioSystem.getClip
val inputStream =
AudioSystem.getAudioInputStream(
new BufferedInputStream(new FileInputStream(wav))
)
clip.open(inputStream)
clip.start()
Thread.sleep(clip.getMicrosecondLength / 1000)
}
现在只要运行sbt test
不管测试成功与否都会播放声音
我在 sbt 中有一个相当长的 运行 任务,我希望在它完成后得到声音通知,即使失败了也能收到通知。我以这种粗鲁的方式部分地到达了那里:
lazy val ding = taskKey[Unit]("plays a ding sound")
ding := {
Seq("play", "-q", "/…/SmallGlockA.wav").run
}
我这样调用上述任务:
sbt> ;test;ding
虽然在任务成功时效果很好,但如果任务失败,它当然不会播放声音,考虑到它是测试,这很可能。
有什么办法可以解决这个问题吗?它不必非常漂亮或超级健壮——这不会被提交,这对我来说只是本地的事情。
我提出的解决方案是为 sbt 创建一个 AutoPlugin
来满足您的需求。
在名为 DingPlugin.scala
的 project
文件夹中创建一个包含以下内容的新文件
import sbt.Keys._
import sbt.PluginTrigger.AllRequirements
import sbt._
object DingPlugin extends AutoPlugin {
private def wavPath = "/path/to/wav"
private def playSound(wav: String) = ???
override def trigger = AllRequirements
override def projectSettings: Seq[Def.Setting[_]] = Seq(
Test / test := (Test / test).andFinally(playSound(wavPath)).value
)
}
重点是方法andFinally
that
defines a new task that runs the original task and evaluates a side effect regardless of whether the original task succeeded. The result of the task is the result of the original task
playSound
的实现是从这个question导出的,代码如下
private def playSound(wav: String): Unit = {
import java.io.BufferedInputStream
import java.io.FileInputStream
import javax.sound.sampled.AudioSystem
val clip = AudioSystem.getClip
val inputStream =
AudioSystem.getAudioInputStream(
new BufferedInputStream(new FileInputStream(wav))
)
clip.open(inputStream)
clip.start()
Thread.sleep(clip.getMicrosecondLength / 1000)
}
现在只要运行sbt test
不管测试成功与否都会播放声音