2011-10-22 88 views
2

我有一个依赖关系图与此类似SBT:导线项目依赖图

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

一个多模块的网络项目,是战争项目依赖于A1而这又取决于A2A3等。

现在在打包战争项目之前,我想将其相关项目中的一些网络资源复制到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

下面的代码添加汇聚清晰度的任务,将集中所有的资源相关的项目:

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