Gradle多项目配置订单管理

Gradle多项目配置订单管理,gradle,build.gradle,Gradle,Build.gradle,编辑: 在Gradle源代码中查看之后,这种行为似乎是有意的,并且是通过在任务容器上使用getByPath、getByName、findByPath和findByName方法触发的,但显然只有当提供的参数值表示任务名称而不是任务路径时才会触发(即,如果它不包含“:”路径分隔符) 看 在实际访问项目任务之前,调用projectAccessListener.beforeRequestingTaskByPath(project);, 而且 实际评估项目的位置 我试图更好地理解管理项目配置顺序的可用方法

编辑: 在Gradle源代码中查看之后,这种行为似乎是有意的,并且是通过在任务容器上使用
getByPath
getByName
findByPath
findByName
方法触发的,但显然只有当提供的参数值表示任务名称而不是任务路径时才会触发(即,如果它不包含“:”路径分隔符)

看 在实际访问项目任务之前,调用
projectAccessListener.beforeRequestingTaskByPath(project);
, 而且 实际评估项目的位置

我试图更好地理解管理项目配置顺序的可用方法。示例有点冗长,但我觉得有必要设置问题的上下文

安装程序 假设我们有一个非常基本的设置,有一个根项目和一个子项目:

master
+--- build.gradle
+--- settings.gradle
+--- lib
 \--- build.gradle
settings.gradle

include 'lib'
rootProject.name = 'master'
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
evaluationDependsOn(':lib')
println "${project.name} config done"
println "${project.name} config start"
project(':lib').ext.flag = true
println "${project.name} config done"
println "${project.name} config start"
println "Property value: ${project.flag}"
println "${project.name} config done"
println "${project.name} config start"
tasks.getByPath(':lib:action').doLast { println "injected task action" }
println "${project.name} config done"
println "${project.name} config start"
tasks.create('action') {
    println ":lib:action configuration started"
}
println "${project.name} config done"
build.gradle

include 'lib'
rootProject.name = 'master'
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
evaluationDependsOn(':lib')
println "${project.name} config done"
println "${project.name} config start"
project(':lib').ext.flag = true
println "${project.name} config done"
println "${project.name} config start"
println "Property value: ${project.flag}"
println "${project.name} config done"
println "${project.name} config start"
tasks.getByPath(':lib:action').doLast { println "injected task action" }
println "${project.name} config done"
println "${project.name} config start"
tasks.create('action') {
    println ":lib:action configuration started"
}
println "${project.name} config done"
lib/build.gradle

include 'lib'
rootProject.name = 'master'
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
evaluationDependsOn(':lib')
println "${project.name} config done"
println "${project.name} config start"
project(':lib').ext.flag = true
println "${project.name} config done"
println "${project.name} config start"
println "Property value: ${project.flag}"
println "${project.name} config done"
println "${project.name} config start"
tasks.getByPath(':lib:action').doLast { println "injected task action" }
println "${project.name} config done"
println "${project.name} config start"
tasks.create('action') {
    println ":lib:action configuration started"
}
println "${project.name} config done"
基本情况 如果我们在顶层目录中执行
gradle项目
,我们将看到以下评估顺序:

master config start
master config done
lib config start
lib config done
这是预期的,因为Gradle文档说项目是按自上而下的顺序配置的:

默认的配置顺序是自顶向下的,这通常是需要的

评价依赖 有一种记录在案的方法可以通过evaluationDependsOn方法更改订单:

build.gradle

include 'lib'
rootProject.name = 'master'
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
evaluationDependsOn(':lib')
println "${project.name} config done"
println "${project.name} config start"
project(':lib').ext.flag = true
println "${project.name} config done"
println "${project.name} config start"
println "Property value: ${project.flag}"
println "${project.name} config done"
println "${project.name} config start"
tasks.getByPath(':lib:action').doLast { println "injected task action" }
println "${project.name} config done"
println "${project.name} config start"
tasks.create('action') {
    println ":lib:action configuration started"
}
println "${project.name} config done"
输出:

master config start
lib config start
lib config done
master config done
因此
evaluationDependsOn
基本上加载
'lib'
构建脚本,对其进行配置,然后恢复主项目配置

从master引用子项目 现在假设我们将向lib项目中注入一个属性:

build.gradle

include 'lib'
rootProject.name = 'master'
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
evaluationDependsOn(':lib')
println "${project.name} config done"
println "${project.name} config start"
project(':lib').ext.flag = true
println "${project.name} config done"
println "${project.name} config start"
println "Property value: ${project.flag}"
println "${project.name} config done"
println "${project.name} config start"
tasks.getByPath(':lib:action').doLast { println "injected task action" }
println "${project.name} config done"
println "${project.name} config start"
tasks.create('action') {
    println ":lib:action configuration started"
}
println "${project.name} config done"
lib/build.gradle

include 'lib'
rootProject.name = 'master'
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
evaluationDependsOn(':lib')
println "${project.name} config done"
println "${project.name} config start"
project(':lib').ext.flag = true
println "${project.name} config done"
println "${project.name} config start"
println "Property value: ${project.flag}"
println "${project.name} config done"
println "${project.name} config start"
tasks.getByPath(':lib:action').doLast { println "injected task action" }
println "${project.name} config done"
println "${project.name} config start"
tasks.create('action') {
    println ":lib:action configuration started"
}
println "${project.name} config done"
输出结果如下:

master config start
master config done
lib config start
Property value: true
lib config done
因此,在主项目中显式引用子项目(
project(':lib')
)不会影响评估顺序,并且属性注入成功

向子项目添加任务 现在,我们将向子项目添加一个任务,并从主项目中引用它:

build.gradle

include 'lib'
rootProject.name = 'master'
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
evaluationDependsOn(':lib')
println "${project.name} config done"
println "${project.name} config start"
project(':lib').ext.flag = true
println "${project.name} config done"
println "${project.name} config start"
println "Property value: ${project.flag}"
println "${project.name} config done"
println "${project.name} config start"
tasks.getByPath(':lib:action').doLast { println "injected task action" }
println "${project.name} config done"
println "${project.name} config start"
tasks.create('action') {
    println ":lib:action configuration started"
}
println "${project.name} config done"
lib/build.gradle

include 'lib'
rootProject.name = 'master'
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
println "${project.name} config done"
println "${project.name} config start"
evaluationDependsOn(':lib')
println "${project.name} config done"
println "${project.name} config start"
project(':lib').ext.flag = true
println "${project.name} config done"
println "${project.name} config start"
println "Property value: ${project.flag}"
println "${project.name} config done"
println "${project.name} config start"
tasks.getByPath(':lib:action').doLast { println "injected task action" }
println "${project.name} config done"
println "${project.name} config start"
tasks.create('action') {
    println ":lib:action configuration started"
}
println "${project.name} config done"
输出为:

master config start
lib config start
:lib:action configuration started
lib config done
master config done
我们看到评估顺序发生了变化:在主配置完成之前,对子项目任务的访问强制子项目的完整配置

问题: 现在谈谈实际问题:

在Gradle文档中,我找不到任何关于哪些操作和命令改变项目配置顺序的详细描述(除了明显的
evaluationDependsOn
evaluationDependsOn子项
)。
是否有关于此主题的可用信息?为什么访问子项目及其属性不会强制其配置,而访问任务则会强制其配置?

非常有趣的发现!您可以在GitHub的Gradle存储库上的一个问题中描述此行为,也许开发人员可以解释原因以及这是否正确计划与否。只知道公共API,我不知道Gradle为什么会这样做,特别是如果一个人知道在尝试访问任务后创建任务的常见问题。@lu.koerfer,你能详细说明访问不存在的任务的问题吗?