如何将InputKey和TaskKey组合成一个新的InputKey?

时间:2015-01-24 13:43:55

标签: sbt

我有一个SBT多项目,其中包括两个子项目。一个是普通的Scala Web服务器项目,另一个是一些Web文件。使用我自己编写的SBT插件,我可以在Web项目上运行Gulp。这个Gulp任务是异步运行的。所以用

sbt "web/webAppStart" "server/run"

我可以并行启动Gulp开发Web服务器和我的Scala后端服务器。现在我想创建一个新任务,将它们组合在一起。所以事后

sbt dev
例如

应该这样做。这是我到目前为止所尝试的:

// Build.sbt (only the relevant stuff)

object Build extends sbt.Build {
  lazy val runServer: InputKey[Unit] = run in server in Compile
  lazy val runWeb: TaskKey[Unit] = de.choffmeister.sbt.WebAppPlugin.webAppStart

  lazy val dev = InputKey[Unit]("dev", "Starts a development web server")

  // Scala backend project
  lazy val server = (project in file("project-server"))

  // Web frontend project
  lazy val web = (project in file("project-web"))

  // Root project
  lazy val root = (project in file("."))
    .settings(dev <<= (runServer) map { (_) => {
      // do nothing
    })
    .aggregate(server, web)

到目前为止这是有效的。现在我不知道如何使dev也依赖于runWeb任务。如果我只是添加runWeb任务,如

.settings(dev <<= (runWeb, runServer) map { (_, _) => {
  // do nothing
})

然后我收到错误

[error] /Users/choffmeister/Development/shop/project/Build.scala:59:value map is not a member of (sbt.TaskKey[Unit], sbt.InputKey[Unit])
[error]     .settings(dev <<= (runWeb, runServer) map { (_, _) =>
[error]                                           ^
[error] one error found
[error] (compile:compile) Compilation failed

有人可以帮我这个吗?

最佳解决方案会将dev的参数传递给runServer任务。但我也可以将dev设为TaskKey[Unit],然后使用硬编码来运行runServer而无需参数。

1 个答案:

答案 0 :(得分:1)

tl; dr 使用.value宏执行相关任务或仅alias任务序列。

使用.value

由于0.13之前的语法(<<=)和project/Build.scala的使用(通常会让人不熟悉sbt的新手),你的案例似乎过于复杂了。

您应该按如下方式在另一个中执行这两个任务:

dev := {
  runWeb.value
  runServer.value
}

完整的例子:

lazy val server = project

lazy val runServer = taskKey[Unit]("runServer")
runServer := {
  println("runServer")
  (run in server in Compile).value
}

lazy val runWeb = taskKey[Unit]("runWeb")
runWeb := {
  println("runWeb")
}

lazy val dev = taskKey[Unit]("dev")
dev := {
  println("dev")
}
dev <<= dev dependsOn (runServer, runWeb)

使用alias命令

sbt提供alias命令......

[sbt-learning-space]> help alias
alias

    Prints a list of defined aliases.

alias name

    Prints the alias defined for `name`.

alias name=value

    Sets the alias `name` to `value`, replacing any existing alias with that name.
    Whenever `name` is entered, the corresponding `value` is run.
    If any argument is provided to `name`, it is appended as argument to `value`.

alias name=

    Removes the alias for `name`.

只需在别名中定义要执行的任务/命令,如下所示:

addCommandAlias("devAlias", ";runServer;runWeb")

使用devAlias就像它是内置任务一样:

[sbt-learning-space]> devAlias
runServer
[success] Total time: 0 s, completed Jan 25, 2015 6:30:15 PM
runWeb
[success] Total time: 0 s, completed Jan 25, 2015 6:30:15 PM