简体   繁体   English

Jenkins 共享库递归 Function 调用

[英]Jenkins Shared Library Recursive Function Calls

I have declarative pipeline and uses jenkins shared library.我有声明性管道并使用 jenkins 共享库。 I am trying to make recursive function call within jenkins shared library.我正在尝试在 jenkins 共享库中进行递归 function 调用。

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.在 xyz.groovy 内部,我有方法 foo,我从我的管道中调用 xyz.foo,该方法有效。 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.我试图了解如何在 jenkins 共享库中调用函数。

this.methodName is rightway to call function recursively inside shared library. this.methodName是在共享库中递归调用 function 的正确方法。 All though method is not a part of class.尽管方法不是 class 的一部分。 But using this.foo() worked for me.但是使用this.foo()对我有用。

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). 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) 并从原始文件 (a.groovy) 调用它。 it worked like a charm:)它就像一个魅力:)

example.例子。

b.groovy 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 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.好处是您可以从闭包中引用方法 args 或方法范围的 state 变量,而不必在递归堆栈中传递它们,因此递归调用可能看起来更简洁一些。 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.缺点是需要额外的样板来进行包装,而且闭包 args 的命名必须不同于方法 args 或 Groovy 会引发错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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