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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7820939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:36:22  来源:igfitidea点击:

Run custom task automatically before/after standard task

scalasbt

提问by Lars Tackmann

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.

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

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-binmy custom tasks is run right before it.

所以我想定义一个自定义任务(比如prepare-app)并将它注入到现有任务的依赖树中(比如package-bin),这样每次有人调用package-bin 时我的自定义任务都会在它之前运行。

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-binright before it packages the compile output into a jar. So how do I alter the above code to be run at the right time ?

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

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 ?.

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

回答by Paul Butcher

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

扩展现有的任务是记录了SBT文件任务(在本节的外观修改现有任务)。

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

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

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

and then modify packageBin to depend on that:

然后修改 packageBin 以依赖它:

packageBin <<= packageBin dependsOn prepareAppTask

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

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

回答by Vladimir Salin

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:

作为@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

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

这与 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:

此外,官方 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
}

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.

在 SBT 1.2.3 上测试过,但也应该与其他 1.x 一起使用。