我是Groovy的新手,来自Java背景。我正在努力学习它,因为它被" Job DSL Plugin"在詹金斯。我试图了解插件主页上发布的示例代码段作为第一步。
以下是他们的代码片段供参考:
branches.each {
def branchName = it.name
job {
name "${project}-${branchName}".replaceAll('/','-')
scm {
git("git://github.com/${project}.git", branchName)
}
steps {
maven("test -Dproject.name=${project}/${branchName}")
}
}
}
我试图理解的是job {
上面的含义。我知道它将成为一个Groovy Closure
,但我不理解语法。我读过的所有Groovy教程都使用了def job = {...}
(定义闭包)或job(...)
(调用闭包)这样的语法。这是其中之一的简写吗?其他情况如scm {
和steps {
- 如何以类似的方式工作?
答案 0 :(得分:4)
如果你定义一个这样的方法:
def job(Closure c) {
println c()
}
然后在Groovy中,您可以致电:
job({
"Hello World"
})
Groovy的解析器允许你省略括号,这样就可以成为:
job {
"Hello World"
}
您可能会看到的另一种形式遵循以下规则:如果CLosure是方法的最后一个参数,则可以在括号外调用它,即:
def job(String who, Closure c) {
println c(who)
}
job("World") { who ->
"Hello $who"
}
答案 1 :(得分:1)
与提到的@tim_yates类似,低级语法是closure
,但在更高级别,这可以被视为builder
- 您可以在MarkupBuilder和{{{{}}中找到好的示例3}}。
我对您使用的插件一无所知,job
,scm
,steps
等是否已预先定义,因为您使用了builder
可以使用methodMissing
方法获得预定义的方法名称或动态方法名称。
只是一个猜测,但可能在插件的内部实现中,有一个名为job
的方法,它实例化一个对象并根据传入的closure
返回它。
BranchBuilder {
Branch branch
Branch job(Closure passedInClosure) {
branch = new Branch()
passedInClosure()
return branch
}
...
}
此passedInClosure
将包含name
,scm
,steps
个闭包,这取决于BranchBuilder
中可能存在的实现:
void name(String branchName) {
branch.name = branchName
}
void scm(Closure passedInClosure) {
// the passedInClosure at this point contains the git closure which maybe isn't explicity defined
passedInClosure()
}
举例说明methodMissing
如何在这种情况下发挥作用(同样在BranchBuilder
中):
def methodMissing(String name, arguments) {
if(name == 'git') {
branch.scms << new SourceControl(system: 'Git', url: arguments[0], branchName: arguments[1])
} else if (name == 'svn') {
branch.scms << new SourceControl(system: 'Subversion', url: arguments[0], branchName: arguments[1])
}
}
JsonBuilder在解释这个问题方面做得比我做得好,但希望我能在某种程度上将其分解。