Gradle 多项目构建的评估顺序

Evaluation order of Gradle multi-project build

我正在使用 Gradle 6.5.1。根据 the Gradle documentation,构建分 3 个阶段进行:初始化、配置和执行。

然而,实际上,事情似乎比这要复杂一些。我在 https://github.com/greenrd/evaluation-order.

有一个最小的、完整的验证示例 (MCVE)

在我看来,配置阶段涉及多个子阶段。

问题通过输入重现

gradle clean :client:test --stacktrace

产生大量输出;但是,关键行是:

Cause 1: org.gradle.internal.resolve.ModuleVersionResolveException: Could not resolve org.typelevel:cats-core_2.12:2.2.0.
Required by:
    project :client > org.http4s:http4s-circe_2.12:0.21.8 > org.http4s:http4s-core_2.12:0.21.8
    project :client > org.http4s:http4s-circe_2.12:0.21.8 > org.http4s:http4s-core_2.12:0.21.8 > org.typelevel:cats-effect_2.12:2.2.0
Caused by: java.lang.IllegalArgumentException: Configuring the dependency resolve details with 'null' version is not allowed.

我心想,“好吧,它为 null 的原因是因为 scalaExt script plugin 在那个时间点还没有被评估”,所以我在 [= 的第 1 行取消注释这段代码16=]:

//apply from: scalaExt

但我的假设似乎不正确,因为它随后给出了 不同的 错误:

Caused by: org.gradle.api.internal.tasks.DefaultTaskContainer$DuplicateTaskException: Cannot add task 'printAll' as a task with that name already exists.

而且至关重要的是,请注意在“Caused by”上方的堆栈跟踪中,未注释的行出现:

       at magnolia_ae70fbynee6mpgv2bzwlr0v6i.run(/home/user/mcve/evaluation-order/gradle/magnolia.gradle:1)

这才是真正奇怪的地方。如果这只是我误解了 Gradle DSL 的语义并混淆了评估顺序的问题,那么取消注释这一行应该可以修复评估顺序,方法是确保脚本插件得到足够早的应用。所以这个“DuplicateTaskException”错误不应该在 第一次 执行这样的 apply from 时发生,但如果它发生了,在 第二次 时间。因为如果是第一次出现,任务怎么可能已经存在了?!

因此在该行未被注释之前的原始项目中,我们似乎处于这种奇怪的半途状态,其中插件脚本已被评估......但它声明的一些变量仍然为空?!这是为什么?我真的很困惑,我无法找到或想出任何解释为什么 Gradle DSL 会以这种奇怪、矛盾的方式运行。一分钟评估顺序是一种方式,然后当您取消注释一行时,评估顺序是其他方式?

多项目 Gradle 构建的真实评估顺序是什么?

这只是一个错字。 cats_v 应该是 cats_core_v