Jenkins 如何将一个类的所有方法动态添加到另一个类中
我在所有管道上隐式加载了一个,然后我的Jenkins 如何将一个类的所有方法动态添加到另一个类中,jenkins,reflection,groovy,jenkins-pipeline,Jenkins,Reflection,Groovy,Jenkins Pipeline,我在所有管道上隐式加载了一个,然后我的Jenkinsfile如下所示: new com.company.Pipeline()() 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
Jenkinsfile
如下所示:
new com.company.Pipeline()()
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.
}
然后,共享库在src/com/company
目录下的Pipeline.groovy
类下面有一些文件:
package com.company
import static Utils.*
def call() {
// some stuff here...
}
问题是,这种方式我必须静态声明所有方法,因此我失去了上下文,没有管道
类”实例,就无法轻松访问jenkins的方法。如您所见,他们将此
传递给方法mvn
考虑到避免这种情况,我想知道如何通过调用Utils来动态地将所有方法添加为闭包。安装this
而不是使用import static Utils.*
,那么我的Utils.groovy类似于:
new com.company.Pipeline()()
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
不能转换为String
的错误,我相信&
不适用于变量,我如何将方法转换为在变量上具有方法名称的闭包?我最喜欢的是一个实例,如果有可能把它变成一个实例,也许问题可以解决,但每当我搜索groovy的方法到闭包转换时,我就找到了&
解决方案
如果我使用instance.metaClass.someMethod=utils.&someMethod
它确实可以工作,但我希望它是动态的,因为我添加了新方法,而不需要担心共享它。有一种方法可以动态地完成它。Notationutils.&someMethod
返回一个可以简单地用构造函数实例化的对象:
MethodClosure(Object owner, String method)
考虑以下示例:
class Utils {
def foo() {
println "Hello, Foo!"
}
def bar() {
println "Hello, Bar!"
}
}
class Consumer {
}
def instance = new Consumer()
def utils = new Utils()
(utils.metaClass.methods*.name - instance.metaClass.methods*.name).each { method ->
def closure = new MethodClosure(utils, method)
closure.delegate = instance
instance.metaClass."$method" = closure
}
instance.foo() // Prints "Hello, Foo!"
instance.bar() // Prints "Hello, Bar!"
在本例中,我使用def closure=newmethodclosure(utils,method)
获取对象方法引用,然后将此方法添加到实例
对象。我希望它能帮上忙。很好,它很有效,只是对于寄存器,我没有使用每个寄存器,因为詹金斯抱怨它不能序列化,但这解决了问题,谢谢。@TiagoPimenta很酷,很高兴我能帮到你:)