我正在构建一个脚本化的Jenkinsfile(用Groovy编写,对此我不太了解,我也不知道Java)
我有一个特定的字符串变量,由于某种原因,该变量不想正常运行,我感到困惑。
[Pipeline] echo
FOOBAR: Mary had a little lamb whose fleece was white as snow
[Pipeline] echo
FOO & BAR: Mary had a little lamb whose fleece was white as snow
结果如您所愿
// THIS DOES NOT WORK AS EXPECTED
@Field def BAR = "and she murdered it"
@Field def FOO = "Mary had a little lamb"
if (FOO) {
BAR = "whose fleece was white as snow"
}
@Field def FOOBAR = "${FOO} ${BAR}"
echo "FOOBAR: ${FOOBAR}"
echo "FOO & BAR: ${FOO} ${BAR}"
但是,以下内容:
[Pipeline] echo
FOOBAR: Mary had a little lamb and she murdered it
[Pipeline] echo
FOO & BAR: Mary had a little lamb whose fleece was white as snow
结果
BAR
我不了解Java / Groovy中事件的顺序是否有些细微差别? (我是一个蟒蛇人)
FOOBAR
被覆盖,但是在定义变量BAR
时会出现,它使用BAR
的原始值,而当在echo语句中简单地构建字符串时,它使用{{ 1}}。什么?!
还是Jenkins与Groovy一起工作的细微差别?
答案 0 :(得分:3)
编写Groovy脚本时,groovy有效地将脚本包装在方法run()
内的标准Java类中。
因此,如果我们删除@Field
批注,则脚本:
def FOO = "Mary had a little lamb"
def BAR = "whose fleece was white as snow"
def FOOBAR = "${FOO} ${BAR}"
echo "FOOBAR: ${FOOBAR}"
echo "FOO & BAR: ${FOO} ${BAR}"
有效地发挥作用:
public class script1582564680906 extends groovy.lang.Script {
public java.lang.Object run() {
java.lang.Object FOO = 'Mary had a little lamb'
java.lang.Object BAR = 'whose fleece was white as snow'
java.lang.Object FOOBAR = "$FOO $BAR"
this.echo("FOOBAR: $FOOBAR")
this.echo("FOO & BAR: $FOO $BAR")
}
}
再加上一些对这个问题不重要的东西...没关系,但是如果您向脚本中添加方法,就像这样:
def something() {
FOO = 'tim'
}
def FOO = "Mary had a little lamb"
def BAR = "whose fleece was white as snow"
def FOOBAR = "${FOO} ${BAR}"
echo "FOOBAR: ${FOOBAR}"
echo "FOO & BAR: ${FOO} ${BAR}"
该类变为:
public class script1582564855552 extends groovy.lang.Script {
public java.lang.Object run() {
java.lang.Object FOO = 'Mary had a little lamb'
java.lang.Object BAR = 'whose fleece was white as snow'
java.lang.Object FOOBAR = "$FOO $BAR"
this.echo("FOOBAR: $FOOBAR")
this.echo("FOO & BAR: $FOO $BAR")
}
public java.lang.Object something() {
FOO = 'tim'
}
}
如您所见,在我的something()
方法中,我试图访问FOO
,但这仅在run()
方法内部有效。
这就是存在@Field
批注的原因。它告诉Groovy将定义上移到类级别,而不是移到run()
内部,因此:
import groovy.transform.Field
@Field def FOO = "Mary had a little lamb"
@Field def BAR = "whose fleece was white as snow"
@Field def FOOBAR = "${FOO} ${BAR}"
echo "FOOBAR: ${FOOBAR}"
echo "FOO & BAR: ${FOO} ${BAR}"
成为这个:
public class script1582565001609 extends groovy.lang.Script {
java.lang.Object FOO = 'Mary had a little lamb'
java.lang.Object BAR = 'whose fleece was white as snow'
java.lang.Object FOOBAR = "$FOO $BAR"
public java.lang.Object run() {
this.echo("FOOBAR: $FOOBAR")
this.echo("FOO & BAR: $FOO $BAR")
}
}
现在我们来解决您的问题......:
@Field def BAR = "and she murdered it"
@Field def FOO = "Mary had a little lamb"
if (FOO) {
BAR = "whose fleece was white as snow"
}
@Field def FOOBAR = "${FOO} ${BAR}"
echo "FOOBAR: ${FOOBAR}"
echo "FOO & BAR: ${FOO} ${BAR}"
并按照上述规则进行转换可以得到:
public class script1582565140864 extends groovy.lang.Script {
java.lang.Object BAR = 'and she murdered it'
java.lang.Object FOO = 'Mary had a little lamb'
java.lang.Object FOOBAR = "$FOO $BAR"
public java.lang.Object run() {
if ( FOO ) {
BAR = 'whose fleece was white as snow'
}
this.echo("FOOBAR: $FOOBAR")
return this.echo("FOO & BAR: $FOO $BAR")
}
}
您可以看到... FOOBAR
被设置为一个字段,因此在您将BAR
修改为'whose fleece was white as snow'
之前是初始化方式
但是FOO和BAR符合您调试它们的期望...
如果可以避免的话,请避免使用@Field
,因为这样会使事情难以推理