I want to be able to add a callback as a parameter in a Jenkins Groovy script. I think a closure is what I need, but I don't know how to do it. Here is the output I want:
enter
hello
exit
JenkinsFile:
def rootDir = pwd()
def tools = load "${rootDir}\\patchBuildTools.groovy"
mainMethod(tools.testCl("hello"))
patchBuildTools.groovy
def mainMethod(Closure test) {
println "enter"
test()
println "exit"
}
def testCl(String message) {
println message
}
This gives me an out put of :
hello
enter
java.lang.NullPointerException: Cannot invoke method call() on null object
Is it possible to get the call order I want?
Update - based on the answer
JenkinsFile:
def rootDir = pwd()
def tools = load "${rootDir}\\patchBuildTools.groovy"
mainMethod("enter", "exit")
{
this.testCl("hello")
}
patchBuildTools.groovy
def mainMethod(String msg1, String ms2, Closure test) {
println msg1
test()
println ms2
}
def testCl(String message) {
println message
}
A closure is an anonymous block of code. In Groovy, it is an instance of the Closure class. Closures can take 0 or more parameters and always return a value. Additionally, a closure may access surrounding variables outside its scope and use them — along with its local variables — during execution.
The delegate of a closure is an object that is used to resolve references that cannot be resolved within the body of the closure itself. If your example was written like this instead: def say = { def m = 'hello' println m } say.delegate = [m:2] say() It prints 'hello', because m can be resolved within the closure.
We can even return closures from methods or other closures. We can use the returned closure to execute the logic from the closure with the explicit call() method or the implicit syntax with just the closure object followed by opening and closing parentheses ( () ).
The Jenkinsfile is written using the Groovy Domain-Specific Language and can be generated using a text editor or the Jenkins instance configuration tab. The Declarative Pipelines is a relatively new feature that supports the concept of code pipeline.
You might have misunderstood how closures work - a closure is an anonymous function which you can pass to another function and execute.
Having said that, in your example you are passing the result of testCl()
, which is a String
, to mainMethod()
. This is wrong, because mainMethod
expects a Closure
and not a String
as the passed argument.
I am not sure what you are trying to achieve, but here is how you could use a Closure
:
Jenkinsfile
def rootDir = pwd()
def tools = load "${rootDir}\\patchBuildTools.groovy"
mainMethod() {
// everything you put here is the closure that will be passed
// as the argument "body" in the mainMethod() (inside patchBuildTools.groovy)
echo "hello world from Closure"
}
patchBuildTools.groovy
def mainMethod(Closure body) {
println "enter"
body() // executes the closure passed with mainMethod() from the Jenkinsfile.
println "exit"
}
Result
enter
hello world from Closure
exit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With