10

我有一个简单的构建工具多项目问题...

我有以下目录结构代表我的 java sbt 项目:

/project1
/project2
/project3

所以所有项目共享一个共同的直接父文件夹。项目 2 和 3 在项目 1 的 build.sbt 中引用,如下所示:

.dependsOn(project2, project3)
.aggregate(project2, project3)

lazy val project2 = ProjectRef(file("../project2"), "project2")

lazy val project3 = ProjectRef(file("../project3"), "project3")

这样,project1 和其他之间就存在依赖关系。

到目前为止一切都很好,一切正常。

但是现在我想在执行其他任何操作之前从 project2 执行 main 方法。当我从父级(project1)执行“运行”任务时,我希望 project2 中的特定类执行其主要方法。我该怎么做呢?sbt 文档解释说“聚合意味着在聚合项目上运行任务也将在聚合项目上运行它。 ”: http ://www.scala-sbt.org/0.13.5/docs/Getting-Started/Multi -Project.html#aggregation

我没有看到我在 projet2 上的主要课程被执行。我还将它添加到 project2 的 build.sbt 中:

mainClass in (Compile, run) := Some("Main")

该项目的目标是在编译时和运行时生成代码。Project2 的工作是生成 Java 和 Javascript 代码。可以在构建其他项目之前生成。

那可能吗?如果没有,我将不得不独立于其他项目运行 project2。

=]

4

2 回答 2

5

如果我有如下所示的结构:

+ root +--- backend +--- frontend 和一个类似于http://www.scala-sbt.org/0.13/docs/Multi-Project.html中所示的 build.sbt 项目,可以说:

lazy val commonSettings = Seq(
  version := "0.1.0-SNAPSHOT",
  scalaVersion := "2.12.1",
  resolvers := allResolvers,
  libraryDependencies := AllLibraryDependencies
)

lazy val client = (project in file("client")).
  //  .enablePlugins(PlayScala)
  settings(commonSettings: _*).
  settings(
    name := "client"
  )
  .aggregate(common, frontend, backend)
  .dependsOn(common, frontend, backend)


lazy val common = (project in file("common")).
  settings(commonSettings: _*).
  settings(
    name := "common"
  )

lazy val frontend = (project in file("frontend")).
  settings(commonSettings: _*).
  settings(
    name := "frontend"
  )
  .aggregate(common)
  .dependsOn(common)

lazy val backend = (project in file("backend")).
  settings(commonSettings: _*).
  settings(
    name := "backend"
  )
  .aggregate(common)
  .dependsOn(common)

`

然后在前端项目中执行一个类,这个命令对我有用:

sbt "frontend/runMain sample.cluster.transformation.frontend.TransformationFrontendApp 2551"

于 2017-05-18T15:26:13.273 回答
3

默认情况下run / aggregatefalse

sbt:root> inspect run / aggregate
[info] Setting: Boolean = false
[info] Description:
[info]  Configures task aggregation.
[info] Provided by:
[info]  Zero / run / aggregate
[info] Defined at:
[info]  (sbt.Defaults.disableAggregate) Defaults.scala:1920
[info] Delegates:
[info]  run / aggregate
[info]  aggregate
[info]  ThisBuild / run / aggregate
[info]  ThisBuild / aggregate
[info]  Zero / run / aggregate
[info]  Global / aggregate
[info] Related:
[info]  Global / aggregate
[info]  Zero / run / aggregate
[info]  Zero / consoleQuick / aggregate
[info]  dependencyCheckPurge / aggregate
[info]  refinedConsole / dependencyCheckUpdateOnly / aggregate
[info]  refinedConsole / dependencyCheckAggregate / aggregate
[info]  server / dependencyCheckListSettings / aggregate
[info]  Zero / changedInputFiles / aggregate
[info]  refinedConsole / dependencyCheckListSettings / aggregate
[info]  refinedConsole / dependencyCheckPurge / aggregate
[info] ...

所以run任务不会被聚合。

即使您将其设置为truethen 您也不太可能得到您想要的,因为聚合任务的顺序是未定义的。

创建任务依赖项是通过相互评估来完成的(正如@akauppi 在旧 SBT 语法中指出的那样):

lazy val project1 = (project in file("project1")
  .settings(
    Compile / run := (project2 / Compile / run).evaluated
  )

现在,如果您还想调用runon ,它会变得有点棘手project1

一种天真的方法是:

lazy val project1 = (project in file("project1")
  .settings(
    Compile / run := {
      (project2 / Compile / run).evaluated
      (project1 / Compile / run).evaluated
    }
  )

但不能保证这将首先运行 project2。

我还没有找到让它工作的方法。

我尝试使用:

(project2 / Compile / run).flatMap((project1 / Compile / run).toTask("").taskValue

但是你得到一个非法的动态引用错误。

我也试过:

Def.sequential((server / Compile / run).toTask(""), (Compile / run).toTask("")).value

但这只会在运行时给出未定义的设置错误。

‍♂️</p>

于 2019-12-12T22:27:20.930 回答