如何在一个子项目中声明该命令取决于sbt中另一个子项目中的命令?

时间:2012-12-08 05:30:29

标签: scala sbt

我的.scala构建定义设置如下:

object build extends Build {
  lazy val root = Project("main", file(".")) aggregate(benchmark)
  lazy val benchmark = Project("benchmark", file("benchmark"))
}

我需要在re-start项目上运行main任务,然后在run上运行benchmark任务(所以我需要确保benchmark/run触发{{1 }})。有没有办法指定这种依赖?

编辑:似乎我找到了解决方案,所以如果有人遇到同样的问题,我会将其添加到这个问题中。我们的想法是创建一个自定义版本的reStart任务,使其成为Task而不是InputTask,因为我们不需要解析参数。完整的build.scala如下:

main/re-start

1 个答案:

答案 0 :(得分:2)

可能有更好的方法可以做到,但这是我的看法:

import sbt._
import Keys._

object MyKeys {
  val restart = TaskKey[Unit]("re-start")
}

object build extends Build {
  import MyKeys._
  lazy val root: Project = Project("main",
    file("."),
    settings = Defaults.defaultSettings ++ Seq(
      restart := { println("***RESTART***") }
    )
  ) aggregate(benchmark)
  lazy val benchmark: Project = Project(
    "benchmark",
    file("benchmark"),
    settings = Defaults.defaultSettings ++ Seq(
      run  in Compile <<= (restart in root, run in Compile in benchmark){
        case (mainRestart, benchmarkRun) =>
          benchmarkRun.mapTask{ runTask => mainRestart.flatMap{ _ => runTask }
        }
      }
    )
  )
}

通过此设置,sbt "project benchmark" run将首先在restart项目上运行main任务,然后实际调用项目run上的标准benchmark命令

请注意,我添加了restart TaskKey(以及main中的虚拟实现)以供说明。

正如您所看到的,这看起来有点涉及到这样一个简单的要求,但使用InputTask s / InputKey s(run是我的(有限)经验一个)总是比它应该的更棘手(而不是简单的Task s / TaskKey更易于处理。)