【问题标题】:How do I access nested configuration values from my custom gradle extension?如何从我的自定义 gradle 扩展访问嵌套配置值?
【发布时间】:2019-12-07 08:44:43
【问题描述】:

我正在编写一个自定义 gradle 插件,它需要从 buildscript 接受任意数量的嵌套参数。比如:

myPlugin{
    configObjects = [
        {
             name="objectA",
             value=5,
        },
        {
             name="objectB",
             value=9,
        }
    ]
}

...configObjects 中的项目数以及其中的值在导入插件的任何构建脚本中定义。

所以在我的插件代码中,我创建了一个扩展...

val config = extensions.create("myPlugin", myPluginTaskConfiguration::class.java, project)

tasks {
    register<myPluginTask>("myPlugin") {
        configObjects= config.configObjects
    }
}

以及一个定义通过扩展接收的数据结构的类:

open class myPluginTaskConfiguration(project: Project) {
    @Input
    @Option(option="configObjects", description = "list of configObjects")
    var configObjects:List<ConfigObject>?=null
}

Gradle 允许我指定外部类型,但显然不能指定内部成员。运行我的插件任务我收到以下错误:

class build_f42r2ugava4a351q5usw8u65g$_run_closure1$_closure5 无法转换为类 com.myplugin.ConfigObject(build_f42r2ugava4a351q5usw8u65g$_run_closure1$_closure5 位于加载程序 org.gradle.groovy.scripts.internal.DefaultScriptCompilationHandler$ScriptClassLoader @224ed88 的未命名模块中.ConfigObject 位于加载器 org.gradle.internal.classloader.VisitableURLClassLoader @72fe231e 的未命名模块中

我不清楚 configObjects 块中对象的类型是什么(嗯,显然它们的类型是 build_f42r2ugava4a351q5usw8u65g$_run_closure1$_closure5,但我认为这不是我可以在作者时使用的东西)

如何从我的 groovy 构建脚本中获取项目列表,并将它们转换为插件中的类型化对象(最好以允许 IDE 向编辑构建脚本的用户提供建议/提示的方式)?

【问题讨论】:

  • 你试过[name: "objectA", ...](地图不是闭包)吗?

标签: gradle kotlin groovy gradle-plugin


【解决方案1】:
  1. @Input@Option 用于任务。从外观上看,您是在将它们用于扩展
  2. 无需在Task 的构造函数中传入project 实例。所有Tasks 都引用了它们属于https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html#getProject--Project

话虽如此,Kotlin 中的完整工作示例将是:

open class MyPluginTaskConfiguration @Inject constructor(objects: ObjectFactory) {
    val configObjects: ListProperty<Map<*, *>> = objects.listProperty()
}

open class MyPluginTask : DefaultTask() {
    @Input
    @Option(option="configObjects", description = "list of configObjects")
    val configObjects: ListProperty<Map<*, *>> = project.objects.listProperty()

    @TaskAction
    fun printMessage() {
        configObjects.get().forEach {
            println("$it")
        }
    }
}

val config = extensions.create("myPlugin", MyPluginTaskConfiguration::class.java)

configure<MyPluginTaskConfiguration> {
    configObjects.set(listOf(
            mapOf<String, Any>(
                    "name" to "objectA",
                    "value" to 5
            ),
            mapOf<String, Any>(
                    "name" to "objectB",
                    "value" to 9
            )
    ))
}

tasks.register("myPlugin", MyPluginTask::class) {
    configObjects.set(config.configObjects)
}

执行上述产生:

./gradlew myPlugin

> Task :myPlugin
{name=objectA, value=5}
{name=objectB, value=9}

更多详情请参考以下文档:

【讨论】:

  • 我的解释正确吗?看起来 configObjects 是在扩展中硬编码的,而不是通过扩展传入的。
猜你喜欢
  • 1970-01-01
  • 2012-11-08
  • 1970-01-01
  • 2012-09-27
  • 2016-08-11
  • 2014-05-08
  • 2020-02-29
  • 1970-01-01
  • 2019-08-24
相关资源
最近更新 更多