sbt子项目聚合和依赖行为

时间:2014-05-07 17:44:07

标签: scala sbt

我有一个带有几个子项目的sbt项目,每个子项目都会发布一些工件,并且有一个相当广泛的测试套件。

当我在CI服务器上运行构建时,我想将工件发布到临时位置,并在发布任务之后运行测试。由于其他人可能想要工件,我想告诉sbt我希望它为所有子项目构建所有工件,然后运行所有测试,因为默认情况下它似乎运行它们以未指定的顺序交错。

我有一个ScopeFilter让我可以访问我的所有子项目,所以我可以让我的ciBuild任务取决于以下内容

(test in Test).all(subprojectScopeFilter).dependsOn(myArtifactsTask.all(subprojectScopeFilter))`

然而,这似乎对订单没有任何实际影响,我肯定会看到一些子项目在其他人运行测试之前运行测试myArtifactsTask。我猜我不完全理解all的工作方式,可能会说每个独立子项目的test任务都依赖于同一个子项目myArtifactsTask?如果是这样,我该如何指定我想要的?它是否记录在某个我错过的地方?该手册描述了all的基础知识,但没有介绍它与其他结构的交互方式。

1 个答案:

答案 0 :(得分:1)

SBT将自动解决任务和项目之间的顺序,并按此顺序构建它们。

你能做的是 - 让我们假设你有三个项目。 Root和两个子项目。我假设密钥myArtifactTask是在根目录中定义的。

project/Build.scala

object MyBuild extends Build {
  val myArtifactTask = TaskKey[Unit]("my-artifact-task", "My Artifact Task")
}

myArtifactTask已在两个子项目中实施。

subproject-a/build.sbt

myArtifactTask := {
  println("myArtifactTask:project-a")
}

subproject-a/build.sbt

myArtifactTask := {
  println("myArtifactTask:project-b")
}

您要做的是以两种项目中调用myArtifactTask的方式定义根build.sbt。然后,您可以定义新任务testedArtifact,这取决于myArtifactTask

build.sbt

lazy val testedArtifact = taskKey[Unit]("Runs myArtifactTask followed by tests")

lazy val inAnyProjectButRoot: ScopeFilter = ScopeFilter (
  inAnyProject -- inProjects(ThisProject)
)

myArtifactTask := {
  myArtifactTask.all(inAnyProjectButRoot).value
}

testedArtifact := {
 (test in Test).all(anyProjectButRoot).value
}

testedArtifact <<= testedArtifact.dependsOn(myArtifactTask)

现在,在根项目中调用testedArtifact将首先调用子项目中的所有myArtifactTask,然后再进行测试。