[英]SBT: How to make one task depend on another in multi-project builds, and not run in the root project?
For my multi-project build, I'm trying to create a verify task that just results in scct:test and then scalastyle being executed in order. 对于我的多项目构建,我正在尝试创建一个只导致scct:test的验证任务,然后按顺序执行scalastyle。 I would like scct:test to execute for all the subprojects, but not the top-level project. 我想scct:test来执行所有子项目,但不是顶层项目。 (If it executes for the top-level project, I get "timed out waiting for coverage report" from scct, since there's no source and no tests in that project.) What I had thought to do was to create verify as a task with dependencies on scct:test and scalastyle. (如果它是针对顶级项目执行的,我会从scct中“等待覆盖率报告超时”,因为该项目中没有源代码和任何测试。)我想要做的是创建一个验证任务依赖于scct:test和scalastyle。 This has turned out to be fairly baroque. 事实证明这是相当巴洛克式的。 Here is my Build.scala from my top-level project/ directory: 这是我的顶级项目/目录中的Build.scala:
object MyBuild extends Build {
val verifyTask = TaskKey[Unit]("verify", "Compiles, runs tests via scct:test and then runs scalastyle")
val scctTestTask = (test in ScctPlugin.Scct).scopedKey
val scalastyleTask = PluginKeys.scalastyleTarget.scopedKey
lazy val root = Project("rootProject",
file("."),
settings = Defaults.defaultSettings ++
ScalastylePlugin.Settings ++
ScctPlugin.instrumentSettings ++
ScctPlugin.mergeReportSettings ++
Seq(
verifyTask in Global := {},
verifyTask <<= verifyTask.dependsOn(scctTestTask, scalastyleTask)
)
) aggregate(lift_webapp, selenium_tests)
lazy val subproject_1 = Project(id = "subproject_1", base = file("subproject_1"))
lazy val subproject_2 = Project(id = "subproject_2", base = file("subproject_2"))
}
However, the verify task only seems to exist for the root project; 但是,验证任务似乎只存在于根项目中; when I run it I don't see the same task being run in the subprojects. 当我运行它时,我看不到在子项目中运行相同的任务。 This is exactly the opposite of what I want; 这与我想要的完全相反; I'd like to issue sbt verify
and have scct:test and scalastyle run in each of the subprojects but not in the top-level project. 我想发布sbt verify
并在每个子项目中运行scct:test和scalastyle,但不在顶级项目中运行。 How might I go about doing that? 我该怎么做呢?
First thing to note is that if you want some task ( verify
, test
, etc) to run in some projects, you need to define them scoped to the subprojects. 首先要注意的是,如果您想在某些项目中运行某些任务( verify
, test
等),则需要将它们定义为子项目的范围。 So in your case, the most straightforward thing to do this is to define verifyTask
in subproject_1
and subproject_2
. 因此,在您的情况下,最直接的做法是在subproject_1
和subproject_2
定义verifyTask
。
lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.0.4"
lazy val verify = taskKey[Unit]("verify")
def verifySettings = Seq(
skip in verify := false,
verify := (Def.taskDyn {
val sk = (skip in verify).value
if (sk) Def.task { println("skipping verify...") }
else (test in Test)
}).value
)
lazy val root = (project in file("."))
.aggregate(sub1, sub2)
.settings(
verifySettings,
scalaVersion in ThisBuild := "2.12.4",
skip in verify := true
)
lazy val sub1 = (project in file("sub1"))
.settings(
verifySettings,
libraryDependencies += scalaTest % Test
)
lazy val sub2 = (project in file("sub2"))
.settings(
verifySettings,
libraryDependencies += scalaTest % Test
)
There was a recent Reddit thread that mentioned this question, so I'll post what I've done there. 最近有一个Reddit主题提到了这个问题,所以我会发布我在那里所做的事情。 If you want to manually aggregate on some subprojects, there's also a technique called ScopeFilter . 如果要手动聚合某些子项目,还有一种称为ScopeFilter的技术。
Note that I am using sbt 1.x here, but it should work with sbt 0.13 some minor change. 请注意,我在这里使用sbt 1.x,但它应该与sbt 0.13一起使用一些小的改动。
lazy val packageAll = taskKey[Unit]("package all the projects")
lazy val myTask = inputKey[Unit]("foo")
lazy val root = (project in file("."))
.aggregate(sub1, sub2)
.settings(
scalaVersion in ThisBuild := "2.12.4",
packageAll := {
(packageBin in Compile).all(nonRootsFilter).value
()
},
myTask := {
packageAll.value
}
)
lazy val sub1 = (project in file("sub1"))
lazy val sub2 = (project in file("sub2"))
def nonRootsFilter = {
import sbt.internal.inc.ReflectUtilities
def nonRoots: List[ProjectReference] =
allProjects filter {
case LocalProject(p) => p != "root"
case _ => false
}
def allProjects: List[ProjectReference] =
ReflectUtilities.allVals[Project](this).values.toList map { p =>
p: ProjectReference
}
ScopeFilter(inProjects(nonRoots: _*), inAnyConfiguration)
}
In the above, myTask
depends on packageAll
, which aggregates (packageBin in Compile)
for all non-root subprojects. 在上面, myTask
依赖于packageAll
,它汇总了所有非根子项目(packageBin in Compile)
myTask
(packageBin in Compile)
。
sbt:root> myTask
[info] Packaging /Users/xxx/packageall/sub1/target/scala-2.12/sub1_2.12-0.1.0-SNAPSHOT.jar ...
[info] Done packaging.
[info] Packaging /Users/xxx/packageall/sub2/target/scala-2.12/sub2_2.12-0.1.0-SNAPSHOT.jar ...
[info] Done packaging.
[success] Total time: 0 s, completed Feb 2, 2018 7:23:23 PM
I may be wrong, but you are defining the verify task dependency only for the current project. 我可能错了,但您只是为当前项目定义了验证任务依赖项。
Maybe you can try: 也许你可以尝试:
Seq(
verifyTask in Global := {},
verifyTask <<= (verifyTask in Global).dependsOn(scctTestTask, scalastyleTask)
)
Or you can add the verifyTask settings to all your modules. 或者,您可以将verifyTask设置添加到所有模块中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.