SBT:遍历项目依赖图

时间:2011-10-22 23:06:41

标签: scala sbt

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

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

战争项目取决于 A1 ,而 A2 A3 依赖于

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

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 中检索它。但是我想避免使用这个解决方案,还有其他方案可以通过编程方式遍历和连接依赖项。

1 个答案:

答案 0 :(得分:1)

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

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
}

我已经提出了一个更完整的例子here