我有一个带有几个子项目的sbt项目,每个子项目都会发布一些工件,并且有一个相当广泛的测试套件。
当我在CI服务器上运行构建时,我想将工件发布到临时位置,并在发布任务之后运行测试。由于其他人可能想要工件,我想告诉sbt我希望它为所有子项目构建所有工件,然后运行所有测试,因为默认情况下它似乎运行它们以未指定的顺序交错。
我有一个ScopeFilter
让我可以访问我的所有子项目,所以我可以让我的ciBuild
任务取决于以下内容
(test in Test).all(subprojectScopeFilter).dependsOn(myArtifactsTask.all(subprojectScopeFilter))`
然而,这似乎对订单没有任何实际影响,我肯定会看到一些子项目在其他人运行测试之前运行测试myArtifactsTask
。我猜我不完全理解all
的工作方式,可能会说每个独立子项目的test
任务都依赖于同一个子项目myArtifactsTask
?如果是这样,我该如何指定我想要的?它是否记录在某个我错过的地方?该手册描述了all
的基础知识,但没有介绍它与其他结构的交互方式。
答案 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
。
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
,然后再进行测试。