问题描述
我在Jenkins共享库中遇到了一些行为,如果有人可以向我解释一下,那就太好了:
第一期
// MultiMethod.groovy
def Foo() { ... }
def Bar() { ... }
// Jenkinsfile
@Library('LibName') _
pipeline {
...
steps {
script {
// Method (1): this will work
def var = new MultiMethod()
var.Foo()
var.Bar()
// Method (2) this will not work
MultiMethod.Foo()
}
}
}
(((1)和(2)方法是在groovy脚本中调用方法的方法。请不要对“方法”一词的这两种用法感到困惑。)
因此,仅当我使用MultiMethod
运算符实例化此new
时,此方法才起作用。
但是,如果我将文件名为multiMethod
(camelCased)而不是MultiMethod
,则可以使用方法(2)来调用脚本中的方法。有人可以解释这种行为吗?
这似乎很好。
第二期
基于以上示例。如果我有一个名为MultiMethod
的groovy文件(我们前面曾看到,如果用new
实例化,我可以使用其方法),我似乎无法实例化MultiMethod
的对象动态加载库时,如下所示:
// Jenkinsfile
pipeline {
...
steps {
script {
// Method (1): this will not work
library 'LibName'
def var = new MultiMethod()
var.Foo()
var.Bar()
}
}
}
如果我尝试这样做,我会得到:
Running in Durability level: MAX_SURVIVABILITY
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup Failed:
WorkflowScript: 11: unable to resolve class multiMethod
@ line 11,column 32.
def mult = new multiMethod()
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
at org.codehaus.groovy.control.compilationunit.applyToSourceUnits(compilationunit.java:958)
at org.codehaus.groovy.control.compilationunit.doPhaSEOperation(CompilationUni
...
最后一个问题
如果可以的话,另一个问题。我注意到人们习惯于写作
return this
在vars
目录中的脚本末尾。有人可以解释这有什么好处吗?如果有人可以在这种机制的工作原理的背景下对此进行解释,我会很高兴,例如为什么这些脚本会变成全局变量?
谢谢
解决方法
第一个问题答案
这是因为 Jenkins 为共享库定义了该标准。为了消除您的疑问,Jenkins 官方 documentation 中确实有很好的解释,如果您按照标准进行操作,它将起作用。像下面的例子:
确保您遵循此文件夹结构
shared-library
├── src
│ └── org
│ └── any
│ └── MultiMethod.groovy
└── vars
└── multiMethod.groovy
multiMethod.groovy
def foo() {
echo "Hello foo from vars/multiMethod.groovy"
}
def bar() {
echo "Hello bar from vars/multiMethod.groovy"
}
一旦你有了这个并且你像 this 这样配置你的共享库,那么你可以在你的 Jenkins 文件中使用 multiMethod.groovy
,如下所示:
Jenkinsfile
@Library('jenkins-shared-library') _
pipeline {
agent any;
stages {
stage('log') {
steps {
script {
multiMethod.foo()
multiMethod.foo()
}
}
}
}
}
为什么会这样? - 它解释了 here
但是要使用 src/org/any/MultiMethod.groovy
文件夹中的 src
,您必须实例化该类并调用该方法。下面是我的例子
MultiMethod.groovy
package org.any
class MultiMethod {
def steps;
MultiMethod(steps) {
this.steps = steps
}
def foo() {
steps.echo "Hello foo from src/org/any/MultiMethod.groovy"
}
def bar() {
steps.echo "Hello bar from src/org/any/MultiMethod.groovy"
}
}
Jenkinsfile
@Library('jenkins-shared-library') _
import org.any.MultiMethod
pipeline {
agent any;
stages {
stage('log') {
steps {
script {
def x= new MultiMethod(this);
x.foo()
x.bar()
}
}
}
}
}
第二题答案
您的第二个问题与 this post 重复。我试图解释并举了一个例子。请看一下。
最后一个问题的答案
如果您这样做,则无需从 return this
中定义的 Jenkins 全局变量中vars
vars/returnThisTest.groovy
def helloWorld() {
echo "Hello EveryOne"
}
或
def helloWorld() {
echo "Hello EveryOne"
}
return this;
两者都是相同的,从 Jenkinsfile 中您可以像 returnThisTest.helloWorld()
一样调用,但是当场景类似于 this 时,return this
可能更有用 - Jenkins 文档中的一个很好的例子