groovy - 等级 : Can't access configuration defined in one project from another project

标签 groovy gradle

我对 gradle 和 groovy 都很陌生。

问题

我有一个非常简单的多项目结构,如下所示:

Root project 'gradle_test'
+--- Project ':sub1'
\--- Project ':sub2'

这就是 sub1 项目的“build.grade”文件的样子:

// build.gradle of sub1 project
task testConfiguration {
    println project(':sub2').configurations.sub2FooConfiguration
}

最后,这是 sub2 项目的“build.grade”文件:

// build.gradle of sub2 project
configurations {
    sub2FooConfiguration
}

非常少。现在,如果我运行 gradle :sub1:testConfiguration,我收到以下错误:

A problem occurred evaluating project ':sub1'.
> Could not find property 'sub2FooConfiguration' on configuration container.

但是,如果 sub1 项目中的 testConfiguration 任务修改如下,则一切正常:

// notice the "<<" (I believe this is calling the 'doLast' method on the task instance)
task testConfiguration << {
    println project(':sub2').configurations.sub2FooConfiguration
}

问题

我认为“testConfiguration”任务的两个版本之间的区别在于,在第一个实例中,将配置闭包传递给任务,而在修改后的版本中,将“正常”闭包传递给该任务被传递给“doLast”方法。

那么,首先我的假设正确吗?

其次,为什么我一开始就无法访问“sub2”项目?

最后,是否可以在第一个实例中(即在配置闭包中)访问“sub2”项目?

[更新]进一步的问题

鉴于“Invisible Arrow”提供的已接受答案,我想问一个有关引用另一个项目配置的最佳实践的进一步问题(即 sub1 中的任务需要使用 sub2 项目生成的存档) 。

我应该声明两个项目之间的评估依赖关系吗?

或者我应该只在执行时引用 sub2 的配置(例如在 doLast() 中)?

或者,我应该在两个项目之间创建依赖项配置吗?

最佳答案

是的,两者之间是有区别的。 构建基本上分为 3 个阶段,即初始化配置执行。这在Build Lifecycle下有详细描述。 Gradle 文档中的章节。

在您的情况下,第一个实例属于配置阶段,无论任务是否执行,都会评估该阶段。这意味着当您开始构建时,闭包中的所有语句都会被执行。

task testConfiguration {
    // This always runs during a build,
    // irrespective of whether the task is executed or not
    println project(':sub2').configurations.sub2FooConfiguration
}

第二个实例属于执行阶段。请注意<<doLast 的简写,并且在执行任务时调用此闭包。

task testConfiguration << {
    // Called during actual execution of the task,
    // and called only if the task was scheduled to be executed.
    // Note that Configuration phase for both projects are complete at this point,
    // which is why :sub1 is able to access :sub2's configurations.sub2FooConfiguration
    println project(':sub2').configurations.sub2FooConfiguration
}

现在来看看为什么第一个实例会出现错误。这是因为 sub2配置阶段项目尚未评估。因此sub2FooConfiguration尚未创建。

为什么?因为 sub1 之间不存在显式求值依赖关系。和sub2 。在你的情况下,sub1需求sub2作为评估依赖项,因此我们可以在 sub1 中添加该依赖项的build.gradle在任务声明之前,如下:

evaluationDependsOn(':sub2')
task testConfiguration {
    println project(':sub2').configurations.sub2FooConfiguration
}

这将确保 sub2总是在 sub1 之前评估(评估意味着项目的配置阶段)。 sub1现在可以访问configurations.sub2FooConfiguration在任务声明结束时。 Multi-project Builds对此进行了详细解释。章节。

在第二个实例中,configurations.sub2FooConfiguration可以访问,因为调用是在任务的执行 block 中(在两个项目的配置阶段之后)。

PS:请注意,如果您颠倒了项目名称,那么第一个实例可能实际上可以工作,因为如果没有显式依赖项,Gradle 会按字母顺序配置项目。但是,当然,您永远不应该依赖于此,并确保显式声明项目之间的依赖关系。

关于groovy - 等级 : Can't access configuration defined in one project from another project,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27881883/

相关文章:

android - 无法在 Release模式下构建应用程序 - keystore 被篡改或密码不正确

android - 如何解决此 Implementation() 错误?

java - android testBuildType 不工作

jenkins - Jenkins 管道中的条件步骤/阶段

grails - Groovy ConfigSlurper : how to modify a closure in a config?

jenkins - 在Jenkins Groovy Script中获取所有管道作业

xml - 使用 Groovy HTTPBuilder 发布 XML 数据

android - 无法找到 androidx.test.runner.AndroidJUnitRunner 的检测信息

gradle - CordaFTP可能由于Artemis无法传输大文件

java - Groovy 不执行 Java-Method(签名包括泛型)