2

我有一个.scala构建定义设置如下:

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

在运行任务之前,我需要re-startmain项目上运行run任务benchmark(所以我需要确保benchmark/run触发器main/re-start)。有没有办法指定这种依赖关系?

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

import sbt._
import Keys._
import cc.spray.revolver.RevolverPlugin.Revolver._
import cc.spray.revolver.Actions._
import cc.spray.revolver.AppProcess

object build extends Build {
  val noArgs = TaskKey[ExtraCmdLineOptions]("no-args")
  val noArgsTask = TaskKey[ExtraCmdLineOptions]("no-args") := { ExtraCmdLineOptions(Nil, Nil) }
  val reStartCustom = TaskKey[AppProcess]("re-start-custom")

  val reStartTask = reStartCustom <<= (streams, state, reForkOptions, mainClass in reStart, fullClasspath in Runtime, reStartArgs, noArgs in root)
    .map(restartApp)
    .updateState(registerAppProcess)
    .dependsOn(products in Compile)

  lazy val root: Project = Project("main", file("."), settings = Defaults.defaultSettings ++ Seq(noArgsTask, reStartTask)) aggregate(benchmark)
  lazy val benchmark: Project = Project("benchmark", file("benchmark"), settings = Defaults.defaultSettings ++ Seq(
    run in Compile <<= (reStartCustom in root, run in Compile in benchmark) {
      case (mainRestart, benchmarkRun) =>
        benchmarkRun.mapTask { runTask => mainRestart.flatMap(_ => runTask) }
    }
  ))
}
4

1 回答 1

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)。

正如您所看到的,对于这样一个简单的要求,这看起来有点复杂,但我的(有限的)经验是,使用InputTasks/ InputKeys(run作为一个)总是比它应该的要复杂得多(与普通Task的 s相比) / TaskKeys 更容易处理)。

于 2012-12-10T11:27:58.230 回答