简体   繁体   中英

Jenkins Shared Library Recursive Function Calls

I have declarative pipeline and uses jenkins shared library. I am trying to make recursive function call within jenkins shared library.

My shared lib structure is something similar to below:

vars/xyz.groovy

Inside xyz.groovy I have method foo, to whom I call xyz.foo from my pipeline which works. However recursive call from

foo(){
foo()   // says No such DSL method
xyz.foo() //says no signature of method: java.lang.class.foo
}

I am trying to understand how to calls functions within jenkins shared library.

this.methodName is rightway to call function recursively inside shared library. All though method is not a part of class. But using this.foo() worked for me.

I was trying something similar to invoke a recursive function with a method declared in the same file.groovy At the end, the option @Sagar gave didn't work for me As a workaround, I created the recursive function in a new file (b.groovy) and invoke it from the original file (a.groovy). it worked like a charm:)

example.

b.groovy

/**
 * recursive function to compare semantic version form package.json and tag version, only evaluate x.x.x version
 * 0 same version
 * 1 package.json version is GREATER than repo tag version
 * -1 package.json version is SMALLER than repo tag version
 */
int call(ArrayList versionPackageJsonSplit, ArrayList versionTagRepoSplit, Integer iteration) {
    if (versionPackageJsonSplit[iteration].toInteger() == versionTagRepoSplit[iteration].toInteger()) {
        if (iteration == 2) {
            println 'return 0'
            return 0
        }
        return utility_cdkCompareVersions (versionPackageJsonSplit, versionTagRepoSplit, iteration+1) // --> recursive invocation
    } else if (versionPackageJsonSplit[iteration].toInteger() > versionTagRepoSplit[iteration].toInteger()) {
        println 'return 1'
        return 1
    } else if (versionPackageJsonSplit[iteration].toInteger() < versionTagRepoSplit[iteration].toInteger()) {
        println 'return -1'
        return -1
    }
}

a.groovy

.
.
.

compareVersionsResult = b (versionPackageJsonSplit, versionTagRepoSplit, 0)
println compareVersionsResult
.
.
.
.


```

So far the least awful way I've found to do this reliably is to create a top-level wrapper method with a recursive closure inside it:

def recursiveMethod(args) {
  Closure rec
  rec = { arg ->
    if (recursiveCase) {
      return rec(…)
    }
    else {
      return baseCase
    }
  }

  return rec(…)
}

The upside is that you can reference method args or method-scoped state variables from within the closure without having to pass them around the recursive stack, so recursive calls may look a little cleaner. The downside is a little extra boilerplate to do the wrapping, and also that the closure args have to be named differently than the method args or Groovy raises an error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM