在标准任务之前/之后自动运行自定义任务

发布于 2024-12-10 11:55:50 字数 798 浏览 0 评论 0原文

我经常想在运行其中一项标准任务之前进行一些自定义。我意识到我可以创建新任务,按照我想要的顺序执行现有任务,但我发现这很麻烦,而且开发人员错过他应该运行 my-compile 而不是编译的机会很大,并导致难以修复错误。

因此,我想定义一个自定义任务(例如 prepare-app)并将其注入到现有任务的依赖关系树中(例如 package-bin),以便每次有人调用 package-bin 我的自定义任务就在它之前运行。

我尝试这样做,

  def mySettings = {
    inConfig(Compile)(Seq(prepareAppTask <<= packageBin in Compile map { (pkg: File) =>
      // fiddle with the /target folder before package-bin makes it into a jar
    })) ++
    Seq(name := "my project", version := "1.0")
  }

  lazy val prepareAppTask = TaskKey[Unit]("prepare-app")

但在将编译输出打包到 jar 之前,它不会由 package-bin 自动执行。那么如何更改上面的代码以在正确的时间运行呢?

更一般地说,我在哪里可以找到有关挂钩其他任务(例如编译)的信息,是否有一种通用方法可以确保您自己的任务在调用标准任务之前和之后运行?

I often want to do some customization before one of the standard tasks are run. I realize I can make new tasks that executes existing tasks in the order I want, but I find that cumbersome and the chance that a developer misses that he is supposed to run my-compile instead of compile is big and leads to hard to fix errors.

So I want to define a custom task (say prepare-app) and inject it into the dependency tree of the existing tasks (say package-bin) so that every time someone invokes package-bin my custom tasks is run right before it.

I tried doing this

  def mySettings = {
    inConfig(Compile)(Seq(prepareAppTask <<= packageBin in Compile map { (pkg: File) =>
      // fiddle with the /target folder before package-bin makes it into a jar
    })) ++
    Seq(name := "my project", version := "1.0")
  }

  lazy val prepareAppTask = TaskKey[Unit]("prepare-app")

but it's not executed automatically by package-bin right before it packages the compile output into a jar. So how do I alter the above code to be run at the right time ?

More generally where do I find info about hooking into other tasks like compile and is there a general way to ensure that your own tasks are run before and after a standard tasks are invoked ?.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

末が日狂欢 2024-12-17 11:55:50

Tasks 的 SBT 文档记录了扩展现有任务(请参阅部分修改现有任务)。

像这样的事情:

compile in Compile <<= (compile in Compile) map { _ => 
  // what you want to happen after compile goes here 
}

实际上,还有另一种方法 - 定义您的任务依赖于编译

prepareAppTask := (whatever you want to do) dependsOn compile

,然后修改 packageBin 以依赖于它:(

packageBin <<= packageBin dependsOn prepareAppTask

以上所有内容均未经测试,但我希望一般推力应该有效)。

Extending an existing task is documented the SBT documentation for Tasks (look at the section Modifying an Existing Task).

Something like this:

compile in Compile <<= (compile in Compile) map { _ => 
  // what you want to happen after compile goes here 
}

Actually, there is another way - define your task to depend on compile

prepareAppTask := (whatever you want to do) dependsOn compile

and then modify packageBin to depend on that:

packageBin <<= packageBin dependsOn prepareAppTask

(all of the above non-tested, but the general thrust should work, I hope).

得不到的就毁灭 2024-12-17 11:55:50

作为 @Paul Butcher 之前答案的更新,这可以在 SBT 1.x 版本中以稍微不同的方式完成,因为不再支持 <<== 。我举了一个在我的项目之一中使用的编译之前运行的示例任务的示例:

lazy val wsdlImport = TaskKey[Unit]("wsdlImport", "Generates Java classes from WSDL")

wsdlImport := {
  import sys.process._
  "./wsdl/bin/wsdl_import.sh" !
  // or do whatever stuff you need
}

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

这与 1.x 之前的完成方式非常相似。

另外,官方 SBT 文档还建议了另一种方法,它基本上是任务的组合(而不是依赖关系层次结构)。与上面相同的例子:

(compile in Compile) := {
  val w = wsdlImport.value
  val c = (compile in Compile).value
  // you can add more tasks to composition or perform some actions with them
  c
}

感觉在某些情况下提供了更多的灵活性,尽管第一个例子看起来更简洁,对我来说。

在 SBT 1.2.3 上进行了测试,但也应该适用于其他 1.x。

As an update for the previous answer by @Paul Butcher, this could be done in a bit different way in SBT 1.x versions since <<== is no longer supported. I took an example of a sample task to run before the compilation that I use in one of my projects:

lazy val wsdlImport = TaskKey[Unit]("wsdlImport", "Generates Java classes from WSDL")

wsdlImport := {
  import sys.process._
  "./wsdl/bin/wsdl_import.sh" !
  // or do whatever stuff you need
}

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

This is very similar to how it was done before 1.x.

Also, there is another way suggested by official SBT docs, which is basically a composition of tasks (instead of dependencies hierarchy). Taking the same example as above:

(compile in Compile) := {
  val w = wsdlImport.value
  val c = (compile in Compile).value
  // you can add more tasks to composition or perform some actions with them
  c
}

It feels like giving more flexibility in some cases, though the first example looks a bit neater, as for me.

Tested on SBT 1.2.3 but should work with other 1.x as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文