【发布时间】:2020-09-19 01:00:37
【问题描述】:
我正在为 Jenkins 开发一个 shared library,我想访问一些类之间的一些实用程序方法,但不是全部,因此我建立了一些声明:
- 我想避免使用静态方法,因为它不直接访问管道步骤,并且每次调用都传递管道实例会很痛苦;
- 我也想避免使用单例,或者在每个方法调用前加上 util 类的实例;
- 由于它不应该在所有类之间共享,我希望避免将每个方法作为文件放在
vars/特殊目录中,但我希望有类似的行为; - 尽管扩展类是一种反模式,但它是可以接受的,但我想避免使用冗长的 Java 语法来声明与文件同名的类,一旦它隐含在 groovy 中;
这个question 确实部分解决了我的问题,尽管序列化存在问题,但我注意到当我使用检查点并且从某个阶段恢复某些构建时,实例会丢失所有额外的方法。
这个other question 可以帮助我解决序列化问题,但是作者似乎已经解决了他的问题的根本原因,使用的方式不是最初的问题标题。
有没有办法在不使用class NameOfFile extends SomeOtherClass { put every thing inside this block } 语法的情况下扩展groovy 中的隐式脚本类?并且不使用内部类?
否则,有没有办法像上一个问题一样使用脚本 groovy 语法类似物来声明构造函数?
甚至,有没有办法改变序列化行为以在反序列化后再次安装额外的方法?
附录
脚本语法或多或少像这样工作:
考虑文件src/cicd/pipeline/SomePipeline.groovy的内容:
package cicd.pipeline
// there is no need to wrap everything inside class SomePipeline,
// since it is implicit
def method() {
// instance method, here I can access pipeline steps freely
}
def static otherMethod() {
// static method, here it is unable to access pipeline steps
// without a instance
}
@groovy.transform.Field
def field
def call() {
// if the class is used as method it will run
this.method()
SomePipeline.otherMethod() // or simply otherMethod() should work
this.field = 'foo'
println "this instance ${this.getClass().canonicalName} should be cicd.pipeline.SomePipeline"
}
// any code other than methods or variables with @Field
// annotation will be inside a implicit run method that is
// triggered likewise main method but isn't a static one
def localVar = 'foo'
println "It will not execute on constructor since it is on run: $localVar"
println "Method: ${org.codehaus.groovy.runtime.StackTraceUtils.sanitize(new Throwable()).stackTrace[0].methodName}"
println "this instance ${this.getClass().canonicalName} should be cicd.pipeline.SomePipeline"
如果我要使用 Java 详细语法,我将不得不将几乎所有内容都包装在 class SomePipeline 中,这在 groovy 中是隐含的,这是我想要保留的脚本语法。
【问题讨论】:
-
你能分享一下预期的语法吗?
-
@daggett 很难说它会是什么,因为这就是我所要求的,我链接的问题表达了我所期望的感受,但我会尝试更好地描述它。
标签: groovy jenkins-pipeline shared-libraries jenkins-groovy