How does Gradle generate a new task from a task rules

一个人想着一个人 提交于 2020-02-23 06:37:10

问题


In section 19.11. of the 4.2.1 user guide is this task rule example. How is the if predicate able to be true before the rule is even executed. I also noticed that when task groupPing is entered before the task rule the build fails. How are the tasks pingServer1, pingServer2 already created before the rule even starts?

tasks.addRule("Pattern: ping<ID>") { String taskName ->
    if (taskName.startsWith("ping")) {
        task(taskName) {
            doLast {
                println "Pinging: " + (taskName - 'ping')
            }
        }
    }
}

task groupPing {
    dependsOn pingServer1, pingServer2
}

回答1:


Per this book excerpt, the mechanism is similar to the methodMissing functionality in Groovy and other languages. That is, if the task does not exist, then Gradle will deliberately check the task rules, which can clearly create tasks dynamically.

To address the comment, consider the following build.gradle:

tasks.addRule("rule 1") { String taskName ->
    println "TRACER xyz before if: ${taskName}"
    if (taskName.startsWith("xyz")) {
        println "TRACER xyz inside if: ${taskName}"
        task(taskName) {
            doLast {
                println "xyz " + (taskName - "xyz")
            }
        }
    }
}

tasks.addRule("rule 2") { String taskName ->
    println "TRACER ping before if: ${taskName}"
    if (taskName.startsWith("ping")) {
        println "TRACER ping inside if: ${taskName}"
        task(taskName) {
            doLast {
                println "Pinging: " + (taskName - "ping")
            }
        }
    }
}

task foo {
    println 'foo: config phase'
    doFirst {
        println 'foo: exec phase first'
    }
    doLast {
        println 'foo: exec phase last'
    }
}

task groupPing {
    dependsOn pingServer1, pingServer2
    println 'groupPing: config phase'
}

In essence, this does:

  • Define "rule 1" which checks the taskName (a String, not a task!) for prefix xyz
  • Define "rule 2" which checks the taskNamefor prefix ping
  • Define task foo with some printlns
  • Define task groupPing with dependencies on dynamic tasks

Here is the output for foo (spacing added). It illustrates that, in the configuration phase, Gradle invokes "rule 1" and then "rule 2" to define pingServer1 and pingServer2:

$ gradle -q foo 
foo: config phase
TRACER xyz before if: pingServer1

TRACER ping before if: pingServer1
TRACER ping inside if: pingServer1

TRACER xyz before if: pingServer2

TRACER ping before if: pingServer2
TRACER ping inside if: pingServer2

groupPing: config phase
foo: exec phase first
foo: exec phase last


来源:https://stackoverflow.com/questions/46964357/how-does-gradle-generate-a-new-task-from-a-task-rules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!