Gradle属性在扩展容器封闭中不可见

时间:2018-09-25 08:16:10

标签: gradle android-gradle build.gradle gradle-plugin

我正在尝试为Gradle编写此自定义插件,但我无法正确地将参数传递给插件。

在插件中,我正在创建一个扩展,如下所示:

@Override void apply(final Project p) {
    p.extensions.create('myPlugin', MyPluginData.class)

然后在MyPluginData内,我正在处理def propertyMissing(String name, value)以接收期望的客户参数。

最后在客户端应用程序build.gradle中,我尝试配置数据:

println("From root value is " + SOME_VALUE)

myPlugin {
    println("From plugin value is " + SOME_VALUE)
    println("But from plugin 'findProperty' value is " + findProperty("SOME_VALUE"))
    clientDataSet = {
        data_1 = SOME_VALUE
        data_2 = findProperty("SOME_VALUE")
        data_3 = "this is a string"

SOME_VALUE是在我的项目gradle.properties上定义的,并且在构建过程中得到了以下日志:

  

来自根值的是来自属性的正确值
  来自插件的值为null
  但是来自插件的'findProperty'值是来自属性的正确值

然后,当然,当接收到data_1的SOME_VALUE为空时,data_2具有正确的值,数据3是我传递的硬​​编码字符串。


我的问题:

我在做什么错或者我的插件上缺少哪个配置,以便客户端应用程序可以直接从其gradle.properties文件中引用属性?


编辑:根据评论的要求

MyPluginData只是extends HashMap<String, MyPluginDataSet>,而MyPluginDataSet只是几个字符串。

因此,在propertyMissing中,我只是将属性名称添加到地图中,并使用字符串创建MyPluginDataSet(稍后将其用于生成自定义任务)。

缺少的属性函数:

def propertyMissing(String name, value) {
    // Create the new data set and add to the map
    def data = new MyPluginDataSet()
    put(name, data)

    // setup and execute the client closure to configure the data
    def closure = value as Closure
    closure.delegate = data
    closure.resolveStrategy = Closure.DELEGATE_FIRST
    closure.run()
}

1 个答案:

答案 0 :(得分:3)

通过使MyPluginDataMap<>继承,我认为您以某种方式“破坏”了属性解析过程(请参阅ExtensionAware),Gradle不会尝试在以下位置搜索“ SOME_VALUE”属性不同的范围(因此它将无法从gradle属性扩展中找到此属性)

也许您可以尝试通过存储内部映射而不是从Map继承来简化MyPluginData类?像这样的东西:

class MyPluginData {
    Map<String, MyPluginDataSet> internalMap = new HashMap<>()

    def propertyMissing(String name, value) {
        println "Entering propertyMissing for name = $name"
        // Create the new data set and add to the map
        def data = new MyPluginDataSet()
        internalMap.put(name, data)

        // setup and execute the client closure to configure the data
        def closure = value as Closure
        closure.delegate = data
        closure.resolveStrategy = Closure.DELEGATE_FIRST
        closure.run()
    }
}