【发布时间】:2023-03-03 20:09:01
【问题描述】:
我在所有管道上隐式加载了一个global shared library on Jenkins,然后我的Jenkinsfile 是这样的:
new com.company.Pipeline()()
然后共享库在目录src/com/company 上有一些文件,在Pipeline.groovy 类下面:
package com.company
import static Utils.*
def call() {
// some stuff here...
}
问题是,这样我必须静态声明所有方法,因此我失去了上下文并且没有Pipeline类的实例就无法轻松访问jenkins的方法。如您所见here 他们将this 传递给方法mvn。
考虑避免这种情况我想知道通过调用Utils.install this而不是使用import static Utils.*来动态添加所有方法作为闭包,然后我的Utils.groovy是这样的:
package com.company
private Utils() {}
static def install(def instance) {
def utils = new Utils()
// Some extra check needed here I know, but it is not the problem now
for (def method in (utils.metaClass.methods*.name as Set) - (instance.metaClass.methods*.name as Set)) {
def closure = utils.&"$method"
closure.delegate = instance
instance.metaClass."$method" = closure
}
}
def someMethod() {
// here I want to use sh(), tool(), and other stuff freely.
}
但它会引发 GStringImpl cannot be cast to String 错误,我相信 .& 不适用于变量,如何将方法转换为在变量上具有方法名称的闭包?我的MetaMethod 主要是CachedMethod 实例,如果可以将其转换为ClosureMetaMethod 实例,也许问题可以解决,但是每当我搜索groovy 的闭包转换方法时,我就找到了@987654344 @解决方案!
如果我使用instance.metaClass.someMethod = utils.&someMethod,它确实可以工作,但我希望它是动态的,因为我添加了新方法而无需担心共享它。
【问题讨论】:
标签: jenkins reflection groovy jenkins-pipeline