我正在使用与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成为一个List来接近这个,但是当我尝试从该类获取属性时,它似乎返回一个动态属性,而不是值。以下是入门插件:
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
我是否认为这一切都错了?如果不是,我如何从动态属性中获取值(尝试获取和值,但这些似乎不起作用)。
感谢您抽出时间阅读本文。
编辑基于@ 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
答案 0 :(得分:6)
一些提示:
无需向autoScaling
添加region
扩展名,因为AsgardRegion
类已具有autoScaling
属性。您只需初始化该属性,并可能添加void autoScaling(Closure closure) { project.configure(autoScaling, closure) }
便捷方法以支持autoScaling { ... }
语法。
project.container
创建NamedDomainObjectContainer
。此容器的文字语法为someName { ... }; otherName { ... }
。没有“普通列表”语法。
您的测试代码为devPhase
容器设置了autoScaling
等,但没有这些属性。这就是您获得动态属性警告的原因。最里面的{ ... }
是一个块(不是闭包)并且是多余的。
要解决列表问题,请为name
定义AsgardAutoScaling
属性并使用常规NamedDomainObjectContainer
文字语法,或者不要使用NamedDomainObjectContainer
并实现自己的句法。例如,您可以在autoScaling
上声明接受闭包的AsgardRegion
方法,创建AsgardAutoScaling
的实例,并将其添加到列表中。
答案 1 :(得分:0)
之前的回答帮助我解决了我的问题。我想将嵌套扩展对象添加到build.gradle
文件中。喜欢这个
family {
father {
firstName = "Ivan"
lastName = "Karamazon"
}
children {
son {
firstName = "Alesha"
lastName = "Rakitka"
}
}
}
最后,我能够做到并创建了示例项目。但是,要求略有不同,所以在这里分享我的经验。有关详细信息,请参阅https://stackoverflow.com/a/41491729/3223198和Github项目https://github.com/andriipanasiuk/family-gradle-plugin