2011-10-22 99 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