SBT:遍历项目依赖图 [英] SBT: Traverse project dependency graph

查看:68
本文介绍了SBT:遍历项目依赖图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多模块 Web 项目,其依赖关系图与此类似

I have a multimodule web project with a dependency graph similar to this

WAR-project
- A1
-- A2
-- A3
- B1
-- B2
---- B22
-- B3

即战争项目依赖于A1,而后者又依赖于A2A3等等.

that is the war project depends on A1 which in turn depends on A2 and A3 and so on.

现在在打包war项目之前,我想从它的依赖项目中复制一些web资源到webapp中.所以我的问题是如何以编程方式遍历 SBT 项目的依赖关系图?即在伪代码中

Now prior to the packageing of the war project I want to copy some web resources from its dependent projects into the webapp. So my question is how do I programmatically traverse a SBT project's dependency graph ? i.e. in pseudu code

resourcesToCopy = []
visitedProjects = []
traverseProjectDependencies(project) {
  visitedProjects += project
  if(project has resourceFolder) {
    resourcesToCopy += resourceFolder.getPath
  }
  for(projectDependency in project) {
    if(projectDependency is not visited) {
      traverseProjectDependencies(projectDependency)
    }
  }
}

注意 我知道如果我将资源文件夹添加到每个依赖项的类路径中,那么我可以从 Web 项目中的 fullClasspath 中检索它.但我想避免这种解决方案,并且还有其他场景,其中以编程方式遍历和与依赖项交互可能会很有用.

Note I am aware that if I add the resource folder to the classpath of each of the dependencies then I could retrieve it from the fullClasspath in the web project. But I would like to avoid this solution and also there are other scenarios where programmatically traversing and interfacing with dependencies could be useful.

推荐答案

以下代码添加了一个 aggr-res 任务,该任务将聚合依赖项目的所有资源:

The following code adds a aggr-res task that will aggregate all resources for dependent projects:

val aggrRes= TaskKey[Seq[File]]("aggr-res", "show aggregate resources")

val aggrResTask = aggrRes in Compile <<= {
  (thisProjectRef, buildStructure) flatMap aggrResources(resources in Compile)
}

def aggrResources[T](key: ScopedTask[Seq[T]])(proj: ProjectRef, struct: Load.BuildStructure) = {
  val deps = collectDeps(_.dependencies.map(_.project))(proj, struct)
  deps.flatMap(key in (_, Compile) get struct.data).join.map(_.flatten)
}

def collectDeps(op: ResolvedProject => Seq[ProjectRef])(projRef: ProjectRef, struct: Load.BuildStructure): Seq[ProjectRef] = {
  val deps = Project.getProject(projRef, struct).toSeq.flatMap(op)
  deps.flatMap(ref => ref +: collectDeps(op)(ref, struct)).distinct
}

我用更完整的例子做了一个要点这里

I have made a gist with a more complete example here

这篇关于SBT:遍历项目依赖图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆