首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SBT:如何在多项目构建中让一个任务依赖于另一个任务,而不是在根项目中运行?

SBT:如何在多项目构建中让一个任务依赖于另一个任务,而不是在根项目中运行?
EN

Stack Overflow用户
提问于 2013-08-25 07:39:31
回答 2查看 3.4K关注 0票数 11

对于我的多项目构建,我试图创建一个验证任务,它只会导致scct:test,然后scalastyle被按顺序执行。我希望对所有子项目执行scct:test,但不是顶级项目。(如果它对顶级项目执行,我会从scct得到"timed out for coverage report“,因为该项目中没有源代码和测试。)我之前想做的是创建一个依赖于scct:test和scalastyle的任务来验证。事实证明,这是相当的巴洛克风格。下面是我的顶级项目/目录中的Build.scala:

代码语言:javascript
复制
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"))
}

但是,验证任务似乎只存在于根项目;当我运行它时,我没有看到相同的任务在子项目中运行。这与我想要的恰恰相反;我想发出sbt verify命令,并在每个子项目中运行scct:test和scalastyle,但不在顶级项目中运行。我该怎么做呢?

EN

回答 2

Stack Overflow用户

发布于 2018-02-03 08:24:32

解决方案1:在子项目中定义verifyTask

首先要注意的是,如果您希望在某些项目中运行某些任务(verifytest等),则需要将它们的范围定义为子项目。因此,在您的示例中,最简单的做法是在subproject_1subproject_2中定义verifyTask

代码语言:javascript
复制
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
  )

解决方案2: ScopeFilter

最近有一个Reddit thread提到了这个问题,所以我将在那里发布我所做的事情。如果您想手动聚合某些子项目,还有一种称为ScopeFilter的技术。

请注意,我在这里使用的是sbt 1.x,但它应该可以与sbt 0.13一起工作,做一些小的更改。

代码语言:javascript
复制
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)
}

在上面的代码中,myTask依赖于packageAll,它聚合了所有非根子项目的(packageBin in Compile)

代码语言:javascript
复制
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
票数 6
EN

Stack Overflow用户

发布于 2013-08-25 17:50:36

我可能错了,但您仅为当前项目定义了验证任务依赖项。

也许你可以试试:

代码语言:javascript
复制
Seq(
   verifyTask in Global := {},
   verifyTask <<= (verifyTask in Global).dependsOn(scctTestTask, scalastyleTask)
)

或者,您可以将verifyTask设置添加到所有模块。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18424250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档