Gradle配置任务基于子项目属性

时间:2018-03-15 14:57:49

标签: gradle build.gradle

我尝试根据子项目中的某个属性配置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

那么,有没有办法在配置时获取子项目的属性?

3 个答案:

答案 0 :(得分:2)

嗯,关键的问题是:在构建的哪一点上所有必要的信息都可用?

由于我们想了解构建中的每个项目,因此将额外的属性toexclude设置为true,并且有可能(通过设计)通过构建脚本来设置该属性,我们需要评估每个构建脚本。

现在,我们有两个选择:

  1. 通过默认,子项目在父(根)项目之后进行评估。为了确保对每个项目进行评估,我们需要等待构建点,评估所有项目。 Gradle为此提供了一个侦听器:

    gradle.addListener(new BuildAdapter() {
        @Override
        void projectsEvaluated(Gradle gradle) {
            tasks.getByPath('zipContent').with {
                exclude allprojects.findAll { it.toexclude }.collect{ it.name }
            }
        }
    })
    
  2. 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) { ... } 
}