如何将任务扩展对象传递给 Gradle 中的闭包?

How can I pass a task extension object to a closure in Gradle?

假设我有一个插件可以将 MyTask.classMyTaskExtension.class 添加到项目中。

MyTaskExtension.class 有五个 setter,其中三个可以跨实例共用。

如何将 MyTaskExtension.class 的类型(用于配置 MyTask.class 的 DSL 的扩展)传递给闭包以便我可以访问其成员? 我的尝试是这样的:

Closure commonSettings = { ExtensionContainer.findByType(MyTask) t -> { 
  t.a = "a"
  t.b = "b"
  t.c = "c"
}}

然后使用此功能 Closure 应用到 Gradle DSL 中的 MyTask 实例。

例如:

task One(type: MyTask) {
  commonSettings.call(this)
  d = "d"
  e = "e"
}
task Two(type: MyTask) {
  commonSettings.call(this)
  d = "4"
  e = "5"
}

相关Grouping/inheriting properties for tasks in Gradle

我采用了使用代表 org.gradle.api.artifacts.ConfigurationContainer 的配置块的方法来设置一组 扩展属性。

如果这是一次性交易(没有任何其他参与者参与 configuration.ext),请使用 configurations.extorg.gradle.api.plugins.ExtraPropertiesExtension 提供的功能):

configurations.ext {
  a = "a"
  b = "b"
  c = "c"
}

或者如果您需要更大的灵活性,请创建您自己的 org.gradle.api.artifacts.Configuration:

configurations {
  commonSettings.ext {
    a = "a"
    b = "b"
    c = "c"
  }
}

然后在一个任务中,只需单独引用元素或编写一些功能代码来循环它们。该循环要求配置中的每个元素都具有名称 name 作为任务配置所期望的元素。

单个元素变体使用 commonSettings:

task One(type: MyTask) {
  a = configurations.commonSettings.a
  b = configurations.commonSettings.b
  c = configurations.commonSettings.c
  d = "d"
  e = "e"
}

使用 commonSettings 的循环元素变体: 一旦我弄清楚如何引用任务本身,这应该会起作用。

task Two(type: MyTask) {
  configurations.commonSettings.ext.properties.each { elem -> this.setProperty(elem.getKey(), elem.getValue()) }
  d = "4"
  e = "5"
}

请注意,为此使用配置的能力是 org.gradle.api.artifacts.Configuration 在其继承树的某处实现了 ExtensionAware 接口这一事实的副产品。配置本身旨在管理文件(配置下的每个元素都是一个文件对象)。配置实际上是为了管理要发布的构建输出文件(他们称之为工件,无论好坏)。参见 org.gradle.api.artifacts.dsl.ArtifactHandler