SBT在所有子项目之后运行任务

时间:2014-11-20 10:16:00

标签: sbt

我想编写一个在所有子项目任务完成后运行的任务。

例如,如果我这样做

sbt a b然后在所有子项目上完成任务a后,我想执行任务b。我不想在每个项目上做(b)。

这可能吗?

事实上,我会接受它,以便我直接修改build.sbt。我不一定要在命令行中指定它。

1 个答案:

答案 0 :(得分:1)

我写了一篇关于这个主题的博文:sequencing tasks with sbt-sequential

addCommandAlias

这是一个例子。我们将在sub1和sub2中定义自定义任务a,在root中定义b。实现顺序执行的最简单方法是使用addCommandAlias,因此我们只是这样做。

lazy val a = taskKey[Unit]("a")
lazy val b = taskKey[Unit]("b")

lazy val root = (project in file(".")).
  aggregate(sub1, sub2).
  settings(addCommandAlias("ab", ";a;b"): _*).
  settings(
    b := {
      println("b")
    }
  )

lazy val sub1 = (project in file("sub1")).
  settings(a := println("a - sub1"))

lazy val sub2 = (project in file("sub2")).
  settings(a := println("a - sub2"))

您可以从shell sbt ab运行此命令。

$ sbt ab
[info] Loading global plugins from ...
[info] Loading project definition from ...
[info] Set current project to root (in build ...)
a - sub2
a - sub1
[success] Total time: 0 s, completed Nov 22, 2014 8:36:18 PM
b
[success] Total time: 0 s, completed Nov 22, 2014 8:36:18 PM

Def.taskDyn

这是另一个例子。这次使用Def.taskDyn,这也是博客文章中的特色。 我是从ScopeFilter构建aggregate,然后我将调度任务a发送给他们。

lazy val a = taskKey[File]("a")
lazy val b = taskKey[Seq[File]]("b")

lazy val root = (project in file(".")).
  aggregate(sub1, sub2).
  settings(
    b := (Def.taskDyn {
      val proj = thisProject.value
      val filter = ScopeFilter(inProjects(proj.aggregate: _*))
      Def.task {
        val allValues = a.all(filter).value
        println(allValues.mkString(","))
        allValues
      }
    }).value
  )

lazy val sub1 = (project in file("sub1")).
  settings(a := new File("a"))

lazy val sub2 = (project in file("sub2")).
  settings(a := new File("b"))

您可以从shell sbt b运行此命令。

$ sbt b
[info] Loading global plugins from ...
[info] Loading project definition from ...
[info] Set current project to root (in build ...)
a,b
[success] Total time: 0 s, completed Nov 23, 2014 9:42:16 PM