如何(重新)定义在根项目上运行以在sbt 0.13中启动聚合的Play(子)项目

时间:2013-12-07 15:18:18

标签: scala sbt playframework-2.2

我正在尝试创建一个多项目SBT构建定义。我在根项目上执行run命令时遇到了问题。

文件夹结构如下:

RootProjectFolder
 |
 |- build.sbt
 |- project
       |
       |-Build.scala
       |-plugins.sbt
 |
 | - play-webapp

Build.scala文件的内容是:

import sbt._
import Keys._
import play.Project._

object ApplicationBuild extends Build {

    val appName         = "project-name"
    val appVersion      = "0.1.0-SNAPSHOT"


    lazy val root = Project(id = appName + "-root", 
                            base = file(".")
                    ).aggregate(webApp)


    lazy val webApp = play.Project(
      appName + "-website", appVersion, path = file("play-webapp")
    )

}

当我启动SBT时,我收到以下消息:Set current project to project-name-root表示正确检测到根项目。

当我执行run命令时,我收到以下错误消息

> run
java.lang.RuntimeException: No main class detected.
        at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last project-name-root/compile:run for the full output.
[error] (project-name-root/compile:run) No main class detected.

错误消息是正确的,说根项目没有任何类,但play-webapp项目有。我假设结果是运行播放应用程序。

如果我在project play-webapp之前输入run,一切似乎都没问题。

这是正确的行为吗?或者我做错了什么?

P.S。我使用的是SBT版本0.13和scala版本2.10.3

2 个答案:

答案 0 :(得分:8)

另一种方法是重新定义run:

lazy val root = Project("root", file("."))
  .aggregate(subproject)
  .settings(
      run := {
        (run in subproject in Compile).evaluated
      }
    )

lazy val subproject = Project(...)

答案 1 :(得分:7)

我真的希望我能更好地解释它,但只有经过大量的试验和错误,我才能找到答案。一旦我学到了更多,就会有更好的解释。

tl; dr 将以下内容添加到RootProjectFolder/build.sbt(在0.13 build.sbt中可以定义多项目设置):

mainClass in `project-name-root` in Compile := (mainClass in `play-webapp` in Compile).value

fullClasspath in `project-name-root` in Runtime ++= (fullClasspath in `play-webapp` in Runtime).value

更长的解释(不一定完整和正确,因此请自行承担风险)。

我假设你的多项目配置如下 - 在sbt shell中运行projects

[project-name-root]> projects
[info] In file:/Users/jacek/sandbox/stackoverflow/sbt-run/
[info]     play-webapp
[info]   * project-name-root

在需要时更改以下项目名称。

在sbt shell中执行inspect run时,您会注意到run任务取决于project-name-root/runtime:fullClasspathproject-name-root/compile:run::mainClass设置。

[project-name-root]> inspect run
[info] Input task: Unit
[info] Description:
[info]  Runs a main class, passing along arguments provided on the command line.
[info] Provided by:
[info]  {file:/Users/jacek/sandbox/stackoverflow/sbt-run/}project-name-root/compile:run
[info] Defined at:
[info]  (sbt.Defaults) Defaults.scala:688
[info] Dependencies:
[info]  project-name-root/compile:run::streams
[info]  project-name-root/runtime:fullClasspath
[info]  project-name-root/compile:run::runner
[info]  project-name-root/compile:run::mainClass
[info] Delegates:
[info]  project-name-root/compile:run
[info]  project-name-root/*:run
[info]  {.}/compile:run
[info]  {.}/*:run
[info]  */compile:run
[info]  */*:run
[info] Related:
[info]  project-name-root/test:run
[info]  sub/compile:run
[info]  sub/test:run

由于我知道如何使用子项目设置的值更改设置,因此我使用:=方法获取根项目的值。它工作正常,但我很确定有更好的方法来实现它。我迫不及待想要找到它们。