3

我目前正在从 gradle4.5 升级到 6.5,我正在处理的项目有一个 stage.gradle,其中包含 200 多个使用 .execute 调用的自定义任务,该任务已被删除。我看过很多关于如何用dependOn/finalizedBy等替换.execute()的文章,但是这不适用于我的用例。

我已经编写了我的任务的代码示例,如下所示

List listFromDB = []
task getListFromServer() {
    doLast{
        listFromDB << dataFromDB
    }
}

task generateConfig() {
    doLast{
        listFromDB.each { item -> 
        
            // code block 1
            
            def javaTask = task "taskName${item.name}"(type TaskJavaFile) {
                param1 = paramTemp1
                param2 = paramTemp2
            }
            javaTask.execute()
            
            // code block 2
            
            def task2 = task "taskName2${item.name}"() {

            // code block 3
            
            } task2.execute()
                    
            // code block 4
        }
    }
}

我试图通过将每个 task.execute 之前和之后的代码分隔成自己的任务来替换此代码。然而,我这样做的方式增加了 listFromDB 循环的多次重复,我无法弄清楚如何在 generateConfig2Executor 或 generateConfig4Executor 中调用代码,因为任务是在运行时创建的,但必须在任务开始之前使用 depondsOn(在 doLast 块之外)。

List listFromDB = []

def TasksRunInOrder(Task... tasks) {
    for(int i =0; i < tasks.length-1; ++i) {
        tasks[i+1].mustRunAfter(tasks[i])
    }
}

task getListFromServer() {
    doLast{
        listFromDB << dataFromDB
    }
}

task generateConfig() {
    def listOfTasks = []
    listOfTasks << getListFromServer
    listOfTasks << generateConfig1
    listOfTasks << generateConfig2
    listOfTasks << generateConfig2Executor
    listOfTasks << generateConfig3
    listOfTasks << generateConfig4
    listOfTasks << generateConfig4Executor
    listOfTasks << generateConfig5
    dependsOn(TasksRunInOrder(*listOfTasks))
}
task generateConfig1() {
    doLast{
        listFromDB.each { item -> 
            // code block 1
        }
    }
}
task generateConfig2() {
    doLast{
        listFromDB.each { item -> 
            task.register("taskName${item.name}",TaskJavaFile) {
                param1 = paramTemp1
                param2 = paramTemp2
            }
        }
    }
}
task generateConfig2Executor() {
    doLast{
        def listOfTasks =[]
         listFromDB.each { item -> 
            listOfTasks << tasks.named("taskName${item.name}").get()
         }
         dependsOn(TasksRunInOrder(*listOfTasks))
    }
}
task generateConfig3() {
    doLast{
        listFromDB.each { item -> 
            // code block 2
        }
    }
}

task generateConfig4() {
    doLast{
        listFromDB.each { item -> 
            task.register("taskName2${item.name}") {
                // codeBlock 3
            }
        }
    }
}

task generateConfig4Executor() {
    doLast{
        def listOfTasks =[]
        listFromDB.each { item -> 
            listOfTasks << tasks.named("taskName2${item.name}").get()
        }
        dependsOn(TasksRunInOrder(*listOfTasks))
    }
}

task generateConfig5() {
    doLast{
        listFromDB.each { item -> 
            // code block 4
        }
    }
}
4

1 回答 1

0

感觉 Gradle 可能不是满足您需求的理想工具……无论如何,这是一种可能的方法:我们使用 Gradle 根据数据库中的项目生成另一个 Gradle 构建。生成的构建随后立即运行。

build.gradle

task getListFromServer() {
    ext.genBuildScript = new File(buildDir, 'myGeneratedBuild/build.gradle')
    doLast{
        // dummy items only to demonstrate:
        List listFromDB = [[name: 'Foo'], [name: 'Bar'], [name: 'Baz']]

        mkdir genBuildScript.parentFile
        genBuildScript.text = '''\
            task runAll() {}
            '''.stripIndent()

        listFromDB.each { item ->
            genBuildScript << """\
                task 'codeBlock1For${item.name}'() {
                    doLast{
                        // code block 1

                        // only to demonstrate:
                        println("\$delegate.name: $item.name")
                    }
                }

                // task type and config only commented for the demo:
                task 'taskName${item.name}'(/*type: TaskJavaFile */) {
                    dependsOn 'codeBlock1For${item.name}'

                    /* param1 = paramTemp1
                    param2 = paramTemp2 */

                    // only to demonstrate:
                    doLast{
                        println("\$delegate.name: $item.name")
                    }
                }

                task 'codeBlock2For${item.name}'() {
                    dependsOn 'taskName${item.name}'

                    doLast{
                        // code block 2

                        // only to demonstrate:
                        println("\$delegate.name: $item.name")
                    }
                }

                task 'taskWithCodeBlock3For${item.name}'() {
                    dependsOn 'codeBlock2For${item.name}'

                    doLast{
                        // code block 3

                        // only to demonstrate:
                        println("\$delegate.name: $item.name")
                    }
                }

                task 'codeBlock4For${item.name}'() {
                    dependsOn 'taskWithCodeBlock3For${item.name}'

                    doLast{
                        // code block 4

                        // only to demonstrate:
                        println("\$delegate.name: $item.name")
                    }
                }

                runAll.dependsOn 'codeBlock4For${item.name}'
                """.stripIndent()
        }

        // only needed if the running order of the tasks generated for the DB
        // items is relevant:
        for (int i = 1; i < listFromDB.size(); i++) {
            def prevItem = listFromDB[i - 1]
            def item = listFromDB[i]
            genBuildScript << """\
                tasks.'codeBlock4For${item.name}'.mustRunAfter(
                    'codeBlock4For${prevItem.name}')
                """.stripIndent()
        }
    }
}

task generateConfig(type: GradleBuild) {
    dependsOn getListFromServer
    dir =  getListFromServer.genBuildScript.parentFile
    buildFile = getListFromServer.genBuildScript
    tasks = ['runAll']
}

运行时

当上面的构建运行时./gradlew --console=verbose generateConfig,它会在控制台打印以下内容:

> Task :getListFromServer

> Task :myGeneratedBuild:codeBlock1ForFoo
codeBlock1ForFoo: Foo

> Task :myGeneratedBuild:taskNameFoo
taskNameFoo: Foo

> Task :myGeneratedBuild:codeBlock2ForFoo
codeBlock2ForFoo: Foo

> Task :myGeneratedBuild:taskWithCodeBlock3ForFoo
taskWithCodeBlock3ForFoo: Foo

> Task :myGeneratedBuild:codeBlock4ForFoo
codeBlock4ForFoo: Foo

> Task :myGeneratedBuild:codeBlock1ForBar
codeBlock1ForBar: Bar

> Task :myGeneratedBuild:taskNameBar
taskNameBar: Bar

> Task :myGeneratedBuild:codeBlock2ForBar
codeBlock2ForBar: Bar

> Task :myGeneratedBuild:taskWithCodeBlock3ForBar
taskWithCodeBlock3ForBar: Bar

> Task :myGeneratedBuild:codeBlock4ForBar
codeBlock4ForBar: Bar

> Task :myGeneratedBuild:codeBlock1ForBaz
codeBlock1ForBaz: Baz

> Task :myGeneratedBuild:taskNameBaz
taskNameBaz: Baz

> Task :myGeneratedBuild:codeBlock2ForBaz
codeBlock2ForBaz: Baz

> Task :myGeneratedBuild:taskWithCodeBlock3ForBaz
taskWithCodeBlock3ForBaz: Baz

> Task :myGeneratedBuild:codeBlock4ForBaz
codeBlock4ForBaz: Baz

> Task :myGeneratedBuild:runAll
> Task :generateConfig

BUILD SUCCESSFUL in 984ms
2 actionable tasks: 2 executed
于 2021-06-30T20:19:01.827 回答