【问题标题】:How to (re)define run on root project to launch aggregated Play (sub)project in sbt 0.13如何(重新)定义在根项目上运行以在 sbt 0.13 中启动聚合的 Play(子)项目
【发布时间】:2013-12-24 22:18:54
【问题描述】:

我正在尝试创建一个多项目 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 项目有。我假设结果是运行 play 应用程序。

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

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

附:我正在使用 SBT 0.13 版和 scala 2.10.3 版

【问题讨论】:

    标签: scala sbt playframework-2.2


    【解决方案1】:

    另一种方法是重新定义运行:

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

    【讨论】:

      【解决方案2】:

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

      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
      

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

      【讨论】:

      • 我接受了您的回答,因为它有帮助,但我还有一个问题。你知道这种行为对于以前的 SBT/Play 组合是否相同?前段时间,当我在玩耍时,我(认为)使用相同的项目结构没有任何问题。这是新事物吗?还是我记性不好?
      • 唉,我不知道。自 0.12 以来我只玩过 sbt,并没有太多 Play 本身可以评论。
      猜你喜欢
      • 2013-12-29
      • 2018-03-13
      • 2013-12-05
      • 2015-09-05
      • 2021-09-08
      • 2014-07-16
      • 2013-03-31
      • 2015-12-02
      • 1970-01-01
      相关资源
      最近更新 更多