gpt4 book ai didi

plugins - 使用嵌套扩展对象编写 gradle 插件

转载 作者:行者123 更新时间:2023-12-02 08:02:56 27 4
gpt4 key购买 nike

我正在开发一个与 Asgard(来自 netflix)集成的 gradle 插件(我不知道 groovy,刚刚开始使用 gradle)。我希望我的扩展对象对于用户来说是这样的:

asgard {
url = "http://asgard"
regions {
"us-east-1" {
autoScaling {
{
devPhase = "test"
min = 3
max = 6
availabilityZones = ["us-east-1a", "us-east-1b", "us-east-1c"]
ami = "Base AMI 2013-07-11"
instanceType = "m3.xlarge"
securityGroups = ["base", "test-application"]
}
}
}
}
}

或者类似的东西。我已经能够通过将 autoScaling 设为列表来接近这一点,但是当我尝试从该类获取属性时,它似乎返回动态属性而不是值。这是下面的入门插件:

import org.gradle.internal.reflect.Instantiator

class AsgardPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("asgard", AsgardPluginExtension, project)
project.asgard.extensions.regions = project.container(AsgardRegion) {String name ->
AsgardRegion region = project.gradle.services.get(Instantiator).newInstance(AsgardRegion, name)
assert region instanceof ExtensionAware

region.extensions.add("autoScaling", project.container(AsgardAutoScaling))

return region
}


project.task('displayConfigs') << {
if(project.asgard.applicationName == null) project.asgard.applicationName = project.name
println "Asgard URL $project.asgard.url"
println "Application name $project.asgard.applicationName"
println "Runs on regions..."
project.asgard.regions.each() {region ->
println "\tRegion $region.name"
println "\tAutoScaling groups..."
region.autoScaling.each() {asg ->
println "\t\tdevPhase $asg"
println "\t\tdevPhase $asg.devPhase"
println "\t\tdevPhase $asg.get('devPhase')"
}
}
}
}
}

class AsgardPluginExtension {
String url = "http://asgard.sisa.samsung.com"
String applicationName

AsgardPluginExtension(Project project) {
applicationName = project.name
}
}

class AsgardRegion {
def String name
List<AsgardAutoScaling> autoScaling
AsgardRegion(String name) { this.name = name }
}

class AsgardAutoScaling {
String devPhase
int min
int max
List<String> availabilityZones
String ami
String instanceType
String sshKey
List<String> securityGroups
}

当我运行任务时,这是我在日志中看到的内容:

$  ./gradlew displayConfigs
:displayConfigs
Asgard URL http://asgard
Application name gradle-asgard-plugin
Runs on regions...
Region us-east-1
AutoScaling groups...
Creating properties on demand (a.k.a. dynamic properties) has been deprecated and is scheduled to be removed in Gradle 2.0. Please read http://gradle.org/docs/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html for information on the replacement for dynamic properties.
Deprecated dynamic property: "devPhase" on "AsgardRegion_Decorated@65087be0", value: "test".
Deprecated dynamic property: "min" on "AsgardRegion_Decorated@65087be0", value: "3".
Deprecated dynamic property: "max" on "AsgardRegion_Decorated@65087be0", value: "6".
Deprecated dynamic property: "availabilityZones" on "AsgardRegion_Decorated@65087be0", value: "[us-east-1a, us-east-1...".
Deprecated dynamic property: "ami" on "AsgardRegion_Decorated@65087be0", value: "Base AMI 2013-07-11".
Deprecated dynamic property: "instanceType" on "AsgardRegion_Decorated@65087be0", value: "m3.xlarge".
Deprecated dynamic property: "securityGroups" on "AsgardRegion_Decorated@65087be0", value: "[base, test-application]".
devPhase
devPhase test
devPhase AsgardRegion_Decorated@14860315('devPhase')

BUILD SUCCESSFUL

Total time: 1.996 secs

我的想法是错的吗?如果不是,我怎样才能从动态属性中获取值(尝试了 get 和 value,但那些似乎不起作用)。

感谢您花时间阅读本文。

根据 @peter-niederwieser 反馈进行编辑

感谢 peter-niederwieser 的提示。在听取了您的建议并查看了闭包的工作原理之后,我想我对如何开始做我想尝试的事情有了更好的理解。

这是现在插件的语法:

asgard {
url = "http://asgard"
regions {
"us-east-1" {
autoScaling {
devPhase = "test"
min = 3
max = 6
availabilityZones = ["a", "b", "c"]
ami = "Base AMI 2013-07-11"
instanceType = "m3.xlarge"
securityGroups = ["base", "test-application"]
}
autoScaling {
devPhase = "stage"
}
}

"us-west-1" {
autoScaling {
devPhase = "test"
}
autoScaling {
devPhase = "stage"
}
}

}
}

可以在这里找到支持此功能的代码:

import org.gradle.internal.reflect.Instantiator

class AsgardPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("asgard", AsgardPluginExtension, project)
project.asgard.extensions.regions = project.container(AsgardRegion) {String name ->
AsgardRegion region = project.gradle.services.get(Instantiator).newInstance(AsgardRegion, name, project)
assert region instanceof ExtensionAware

return region
}


project.task('displayConfigs') << {
if(project.asgard.applicationName == null) project.asgard.applicationName = project.name
println "Asgard URL $project.asgard.url"
println "Application name $project.asgard.applicationName"
println "Runs on regions..."
project.asgard.regions.each() {region ->
println "\tRegion $region.name"
println "\tAutoScaling groups..."
region.autoScaling.each() {asg ->
println "\t\tdevPhase $asg.devPhase"
}
}
}
}
}

class AsgardPluginExtension {
String urlgg
String applicationName

AsgardPluginExtension(Project project) {
applicationName = project.name
}
}

class AsgardRegion {
String name
Project project
List<AsgardAutoScaling> autoScaling = []

AsgardRegion(String name, Project project) {
this.name = name
this.project = project
}

void autoScaling(Closure closure) {
def asg = new AsgardAutoScaling()
project.configure(asg, closure)
autoScaling.add(asg)
}
}

class AsgardAutoScaling {
String devPhase
int min
int max
List<String> availabilityZones
String ami
String instanceType
String sshKey
List<String> securityGroups
}

这是我运行时看到的输出:

$  ./gradlew displayConfigs
:displayConfigs
Asgard URL http://asgard
Application name gradle-asgard-plugin
Runs on regions...
Region us-east-1
AutoScaling groups...
devPhase test
devPhase stage
Region us-west-1
AutoScaling groups...
devPhase test
devPhase stage

BUILD SUCCESSFUL

Total time: 1.929 secs

最佳答案

一些提示:

  • 无需向 region 添加 autoScaling 扩展,因为 AsgardRegion 类已经具有 autoScaling 属性。您只需要初始化该属性,并可能添加一个 void autoScaling(Closureclosure) { project.configure(autoScaling,closure) } 便捷方法来支持 autoScaling { ... } 语法。

  • project.container 创建一个 NamedDomainObjectContainer。该容器的字面语法为 someName { ... }; otherName { ... }。没有“简单列表”语法。

  • 您的测试代码为 autoScaling 容器 设置了 devPhase 等,而该容器没有这些属性。这就是为什么您会收到动态属性警告。最里面的 { ... } 是一个 block (不是闭包)并且是多余的。

要解决列表问题,请为 AsgardAutoScaling 定义 name 属性并使用常规 NamedDomainObjectContainer 文字语法,或者不使用NamedDomainObjectContainer 并实现您自己的语法。例如,您可以在 AsgardRegion 上声明一个 autoScaling 方法,该方法接受闭包,创建 AsgardAutoScaling 的实例,并将其添加到列表中。

关于plugins - 使用嵌套扩展对象编写 gradle 插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17626607/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com