Сложная задача обновления Gradle 4.выполните() замену

#gradle #build.gradle #upgrade #gradle-6.5.1

Вопрос:

В настоящее время я обновляю с gradle4.5 до 6.5, проект, над которым я работаю, имеет этап.gradle с более чем 200 пользовательскими задачами, называемыми с .execute, которые с тех пор были удалены. Я видел много записей о том, как заменить .execute() на dependsOn/finalizedBy и т. Д., Однако это не может работать для моего случая использования.

Я написал пример кода для своих задач следующим образом

 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
        }
    }
}
 

Я попытался заменить этот код, разделив код до и после каждой задачи.выполнить на свои собственные задачи. Однако то, как я это сделал, добавило многократное повторение циклов 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
        }
    }
}
 

Комментарии:

1. У тебя была возможность попробовать мое предложение?

Ответ №1:

Похоже, что 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