Gradle 属性在扩展容器闭包内不可见
Gradle properties not visible inside extension container closure
我正在尝试为 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
上定义的,我在构建过程中得到了以下日志:
From root value is correct value from properties
From plugin value is null
But from plugin 'findProperty' value is correct value from properties
当然,当收到 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()
}
通过使 MyPluginData
继承自 Map<>
,我认为您以某种方式 "break" 属性 解析过程(参见 ExtensionAware)和 Gradle 不会尝试在不同范围内搜索 "SOME_VALUE" 属性(因此它不会从 gradle 属性扩展中找到此 属性)
也许您可以尝试通过存储内部映射而不是从 Map 继承来简化您 MyPluginData
class?类似的东西:
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()
}
}
我正在尝试为 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
上定义的,我在构建过程中得到了以下日志:
From root value is correct value from properties
From plugin value is null
But from plugin 'findProperty' value is correct value from properties
当然,当收到 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()
}
通过使 MyPluginData
继承自 Map<>
,我认为您以某种方式 "break" 属性 解析过程(参见 ExtensionAware)和 Gradle 不会尝试在不同范围内搜索 "SOME_VALUE" 属性(因此它不会从 gradle 属性扩展中找到此 属性)
也许您可以尝试通过存储内部映射而不是从 Map 继承来简化您 MyPluginData
class?类似的东西:
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()
}
}