Reputation: 6069
I am totally new to Groovy, coming from a Java background. I am trying to learn it because it's used by the "Job DSL Plugin" in Jenkins. I'm trying to understand the example code snippet posted on the plugin's homepage as a first step.
Here's a snippet of their code for reference:
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}")
}
}
}
What I'm trying to understand is what job {
means above. I know it's going to be a Groovy Closure
but I don't understand the syntax. All the Groovy tutorials I have read have used a syntax like def job = {...}
(defining a closure) or job(...)
(calling a closure). Is this a shorthand for one of those? How about the other instances like scm {
and steps {
- are they working in a similar way?
Upvotes: 1
Views: 200
Reputation: 1870
Like @tim_yates mentioned, the low-level syntax is a closure
but at a higher level this fwould be considered a builder
- you can find good examples in MarkupBuilder and JsonBuilder.
I don't know anything about the plugin you are using and whether the job
, scm
, steps
, etc. are predefined, because with a builder
you can have predefined method names or dynamic method names with the help of the methodMissing
method.
Just a guess, but possibly within the plugin's internal implementation, there is a method named job
that instantiates an object and returns it based on the passed in closure
.
BranchBuilder {
Branch branch
Branch job(Closure passedInClosure) {
branch = new Branch()
passedInClosure()
return branch
}
...
}
This passedInClosure
would contain name
, scm
, steps
closures which depending on the implementation would probably exist in the 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()
}
To give an example of how the methodMissing
could work in this situation (also in 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])
}
}
The Groovy Goodness site does a better job than I can in explaining this but hopefully I've broken it down somewhat.
Upvotes: 1
Reputation: 171054
if you define a method like so:
def job(Closure c) {
println c()
}
Then in Groovy, you can call:
job({
"Hello World"
})
And Groovy's parser lets you omit the parentheses, so that can just become:
job {
"Hello World"
}
Another form you may see follows the rule that if a CLosure is the last parameter of a method, it can be called outside of the parentheses, ie:
def job(String who, Closure c) {
println c(who)
}
job("World") { who ->
"Hello $who"
}
Upvotes: 4