如何在 SBT 任务中从 SBT 项目中获取所有子项目的依赖项?

如何在 SBT 任务中从 SBT 项目中获取所有子项目的依赖项?

问题描述:

我正在写一个SBT任务,可以输出依赖信息,按项目分组(比如一个SBT项目有多个项目)

I'm write a SBT task, which can output the dependencies information, grouped by project (say a SBT project has multi projects)

我知道有一个 sbt-dependency-graph 插件,但我可以直接使用,因为我想生成一个json文件,但是那个插件只是把依赖树输出到console,没有返回数据对象,不容易得到我想要的数据.

I know there is a sbt-dependency-graph plugin, but I can use it directly, because I want to generate a json file, but that plugin just output the dependency tree to console, without returning an data object, I can't easily get the data I want.

我发现update 任务返回一个UpdateReport,其中包含很多我想要的信息,但它只属于当前项目.在命令行中,如果我想知道所有项目的信息,可以通过projects命令手动显示所有项目,通过someproject/update一一查看.

I found the update task returns a UpdateReport which contains a lot of information I want, but it only belong to the current project. In command line, if I want to know the information of all project, I can manually show all the projects by projects command, and view them one by one by someproject/update.

但是如何在 SBT 任务中做同样的事情呢?我试过了:

But how to do the same in a SBT task? I tried:

val reports = projects.toList.map(prj => (update in prj).value)

它报告:

[error] /Users/me/workspace/sbt-test/project/Build.scala:51: Illegal dynamic reference: prj
[error]     val reports = projects.toList.map(prj => (update in prj).value)
[error]                                                         ^
[error] one error found

如何解决?

更多代码:

import sbt._
import sbt.Keys._

object DemoBuild extends Build {

  lazy val allUpdate = taskKey[Unit]("show update reports of all projects")

  lazy val core = project
  lazy val web = project

  lazy val allUpdateDef = allUpdate := {
    val reports = projects.toList.map(prj => (update in prj).value)
    println(reports)
  }

  lazy val root = (project in file("."))
    .settings(
      allUpdateDef
    )

}

查看文档后:http://www.scala-sbt.org/0.13/docs/Tasks.html,我找到了解决方案:

After checking the document: http://www.scala-sbt.org/0.13/docs/Tasks.html, I found the solution:

import sbt._
import sbt.Keys._

object DemoBuild extends Build {

  lazy val groupByProject: Def.Initialize[Task[(String, UpdateReport)]] =
    Def.task {
      (thisProject.value.id, (update in thisProject).value)
    }

  lazy val filter = ScopeFilter(inAnyProject, inAnyConfiguration)

  updateByProject := {
    val subProjects = groupByProject.all(filter).value.map { case (  projectName, updateReport) =>
      ...
    }
  }
}