我尝试根据子项目中的某个属性配置Zip任务,但在配置任务时该属性尚不可访问。例如,我想从我的zip文件中排除所有toexclude = true
的项目。因此,我要排除的子项目的build.gradle
以此开头:
ext.toexclude = true;
...
我的主build.gradle
有这个任务:
task zipContent (type: Zip){
def excludedProjects = allprojects.findAll{Project p -> p.toexclude == true}.collect{it.name}
println excludedProjects
destinationDir = "/some/path"
baseName = "myFile.zip"
exclude excludedProjects
from "/some/other/path"
}
问题是excludedProjects
始终为空。实际上,当我执行任务时,我可以看到[]
。我相信这是因为我在子项目build.gradle
中设置的属性在配置任务时不可用。作为证明,如果我用这个替换任务的第一行:
def excludedProjects = allprojects.collect{it.name}
该任务打印出我项目的所有名称,而zip文件中没有任何内容(这意味着问题出在p.toexclude == true
)。
另外,如果我试试这个:
task zipContent (type: Zip){
def excludedProjects = []
doFirst{
excludedProjects = allprojects.findAll{Project p -> p.toexclude == true}.collect{it.name}
println "IN DOFIRST"
println excludedProjects
}
println "IN TASK CONFIG"
println excludedProjects
destinationDir = "/some/path"
baseName = "myFile.zip"
exclude excludedProjects
from "/some/other/path"
}
任务打印出IN TASK CONFIG
后面跟一个空数组,然后是IN DOFIRST
,数组只包含我设置的子项目ext.toexclude == true
。
那么,有没有办法在配置时获取子项目的属性?
答案 0 :(得分:2)
嗯,关键的问题是:在构建的哪一点上所有必要的信息都可用?
由于我们想了解构建中的每个项目,因此将额外的属性toexclude
设置为true
,并且有可能(通过设计)通过构建脚本来设置该属性,我们需要评估每个构建脚本。
现在,我们有两个选择:
通过默认,子项目在父(根)项目之后进行评估。为了确保对每个项目进行评估,我们需要等待构建点,评估所有项目。 Gradle为此提供了一个侦听器:
gradle.addListener(new BuildAdapter() {
@Override
void projectsEvaluated(Gradle gradle) {
tasks.getByPath('zipContent').with {
exclude allprojects.findAll { it.toexclude }.collect{ it.name }
}
}
})
Gradle提供了方法evaluationDependsOnChildren()
,用于求反顺序。在查询排除的项目之前,可以通过调用此方法来使用您的原始方法。由于此方法仅适用于子项目,因此您可以尝试为构建中的每个项目调用evaluationDependsOn(String)
,以同时申请“兄弟”项目。由于此解决方案破坏了Gradle的默认行为,因此可能会产生不良后果。
答案 1 :(得分:1)
只需在任务之外定义excludedProjects
def excludedProjects = allprojects.findAll{Project p -> p.toexclude == true}.collect{it.name}
task zipContent (type: Zip){
destinationDir = file("/some/path")
baseName = "myFile.zip"
exclude excludedProjects
from "/some/other/path"
}
答案 2 :(得分:1)
您可以在根项目中调用evaluationDependsOnChildren(),以便在根之前评估子项目
例如
evaluationDependsOnChildren()
task zipContent (type: Zip) { ... }
另一种选择是使用afterEvaluate { ... }闭包来延迟评估
例如:
afterEvaluate {
task zipContent (type: Zip) { ... }
}