【问题标题】:SBT: Traverse project dependency graphSBT:遍历项目依赖图
【发布时间】:2011-11-07 20:09:31
【问题描述】:

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

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

即战争项目依赖于A1,而A2又依赖于A3等等。

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

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 中检索它。但我想避免这种解决方案,而且还有其他情况下,以编程方式遍历和与依赖项交互可能会很有用。

【问题讨论】:

    标签: scala sbt


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2018-03-20
      • 1970-01-01
      • 2011-08-27
      • 2011-05-30
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 2020-01-20
      • 2016-04-05
      相关资源
      最近更新 更多