Gradle根据子项目属性配置任务

Gam*_*ega 4 gradle build.gradle

我正在尝试根据子项目内的属性之一配置 Zip 任务,但在配置任务时该属性尚无法访问。例如,我想toexclude = true从 zip 文件中排除所有项目。因此,build.gradle我要排除的子项目是这样开始的:

ext.toexclude = true;
...
Run Code Online (Sandbox Code Playgroud)

我的主要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"
}
Run Code Online (Sandbox Code Playgroud)

问题是它excludedProjects总是空的。确实,当我执行任务时,我可以看到[]。我相信这是因为我在子项目中设置的属性build.gradle在配置任务时不可用。作为证明,如果我将任务的第一行替换为:

def excludedProjects = allprojects.collect{it.name}
Run Code Online (Sandbox Code Playgroud)

该任务打印出我的所有项目名称,并且 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"
}
Run Code Online (Sandbox Code Playgroud)

该任务打印出来IN TASK CONFIG,后跟一个空数组,然后IN DOFIRST该数组仅包含我设置的子项目ext.toexclude == true

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

Luk*_*fer 6

那么,关键的问题是:在构建的哪个阶段所有必要的信息都可用?

由于我们想了解构建中的每个项目,额外属性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 }
            }
        }
    })
    
    Run Code Online (Sandbox Code Playgroud)
  2. Gradle 提供了方法evaluationDependsOnChildren()来扭转评估顺序。在查询排除的项目之前,可以通过调用此方法来使用原始方法。由于此方法仅适用于子项目,因此您可以尝试调用evaluationDependsOn(String)构建中的每个项目来也申请“兄弟”项目。由于此解决方案破坏了 Gradle 默认行为,因此可能会产生不良副作用。