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
。
我正在使用 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
。