Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the jenkinsfile use a closure in this way?

It's a common pattern to write Jenkins pipeline code like this:

def call(body) {    
    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config
    body()
}

I'm not sure how to word this simply, but this closure get implicitly imported and can be called by the file name of the .groovy file it lives in.

I call it like:

MyClosure { myarg = 'sdfsdf' }

I not entirely sure what this is doing. It's doing call(body) and then assigning body as the delegate. so that means the closure I pass it is the delegate, but isn't that just the owner? Wah? me confused.

like image 523
red888 Avatar asked Oct 04 '17 20:10

red888


People also ask

What is a Jenkins closure?

The Groovy documentation explains that, “A closure in Groovy is an open, anonymous, block of code that can take arguments, return a value and be assigned to a variable. A closure may reference variables declared in its surrounding scope.”

What is the purpose of a Jenkinsfile?

Creating a Jenkinsfile , which is checked into source control, provides a number of immediate benefits: Code review/iteration on the Pipeline. Audit trail for the Pipeline. Single source of truth for the Pipeline, which can be viewed and edited by multiple members of the project.

What is Jenkinsfile in Jenkins?

A Jenkinsfile is a text file that contains the definition of a Jenkins Pipeline and is checked into source control. Consider the following Pipeline which implements a basic three-stage continuous delivery pipeline.

Where does the Jenkinsfile go?

Default place where Jenkins is looking for a Jenkinsfile is the root of the project with Jenkinsfile as the filename. Jenkinsfile can be put in any directory and the filename can be whatever you want.


1 Answers

When this runs, it is creating an empty map (config). Then it is telling the closure (body) to look at the delegate first to find properties by setting its resolveStrategy to be the constant Closure.DELEGATE_FIRST. Then it assigns the config map as the delegate for the body object.

Now when you execute the body() closure, the variables are scoped to the config map, so now config.myarg = 'sdfsdf'.

Now later in the code you can have easy access to the map of values in config.

body is the owner, and by default is the delegate. But when you switch the delegate to be config, and tell it to use the delegate first, you get the variables config's scope.

like image 51
Rob Hales Avatar answered Oct 05 '22 14:10

Rob Hales