gradle - Gradle和插件扩展关闭执行顺序

标签 gradle groovy closures gradle-plugin

我有3个插件“A”,“B”和“C”。插件“A”包括具有以下内容的插件“B”:

project.getPlugins().apply(B.class);

插件“B”包括具有以下内容的插件“C”:
project.getPlugins().apply(C.class);

总而言之,相关性为:A> B> C

插件“A”具有自定义任务“T_A”和自定义扩展名“E_A”。插件“C”具有自定义扩展名“E_C”。

当我使用以下build.gradle并执行gradlew T_A时,一切都按预期工作,这意味着在执行T_A之前设置了属性:
plugins {
  id 'A'
}

E_A {
  prop_a = 'hello'
}

E_C {
  prop_c = 'world'
}

但是,具有以下build.gradle:
plugins {
  id 'A'
}

E_C {
  prop_c = 'world'
}

E_A {
  prop_a = 'hello'
}

...然后,在执行任务之前不会设置prop_a。

我被困住了,真的不明白为什么可能错了。
build.gradle文件中扩展名的关闭顺序重要吗?

最佳答案

在配置阶段,调用应用函数时,不能保证某些值被设置为。因此,顺序确实很重要,但是依靠顺序是一个坏习惯。复杂的扩展名(例如NamedDomainObjectContainer)总是延迟配置的。

首先,您可以在任务中使用Property,一旦需要就可以设置它们的值。这是首选方法,因为它可以最大程度地 reduce task 配置,但可能会非常困惑,它是显示如何使用属性的指南:Lazy Configuration: connecting properties together尽管它使用Groovy,但应该易于转换成Java。

还有另一种解决方案,即添加评估后的侦听器。一旦配置了所有插件和扩展名,就会调用该方法,但是如果多个插件配置相同的任务,则可能会变得困惑。参见讨论project afterEvaluate usage的线程。在旁注中,某些Gradle官方插件仍按值配置任务。

class PluginA implements Plugin<Project> {
    ExtensionA a;
    public void apply(Project project) {
        a = project.getExtension().create("E_A", ExtensionA.class);
        project.getTasks().register("T_A");   //prop_a may not be set here
        project.getTasks().findByName("T_A").doLast(t -> System.out.println(a.prop_a));
        project.afterEvaluate(p -> 
            //prop_a will be set here
            p.getTasks().findByName("T_A").doLast(t -> System.out.println(a.prop_a));
        );
    }
}

显然,您可以使它更整洁。

我建议您与听众一起玩,以更好地了解Gradle的生命周期。

关于gradle - Gradle和插件扩展关闭执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61673427/

相关文章:

git - 如何使用 Groovy 脚本执行 Git checkout ?

jquery - 如何将 jquery 自动完成与 var 一起使用?

javascript - JavaScript 中的调用堆栈变量

compiler-construction - 了解编译器中递归闭包的建模

eclipse - Gradle 多项目最佳实践

spring-boot - 如何在基于Gradle的Spring Boot 2.0.0应用程序中检测开发和生产环境?

android - 无法在android studio中构建apk

java - 在 Gradle 中创建 API 编程变体

swing - 在 Fest 中实现匹配器的 Groovy 闭包

groovy - 如何在groovy中屏蔽输入