println 在“调用"中“vars/foo.groovy"的方法;有效,但不在课堂上的方法中 [英] println in "call" method of "vars/foo.groovy" works, but not in method in class

查看:11
本文介绍了println 在“调用"中“vars/foo.groovy"的方法;有效,但不在课堂上的方法中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在迭代构建一个 Jenkins 管道共享库,所以我的 Jenkinsfile 更干净一些.

I'm iterating through building a Jenkins pipeline shared library, so my Jenkinsfile is a little cleaner.

我正在使用以下页面进行指导:https://jenkins.io/doc/book/pipeline/shared-libraries/ .

I'm using the following page for guidance: https://jenkins.io/doc/book/pipeline/shared-libraries/ .

我首先在单个文件中定义了几个方法,例如vars/methodName.groovy",在代码中使用call()"方法.这工作正常,我特别注意到这些方法中的println"调用在 Jenkins 控制台输出中可见.

I first defined several methods in individual files, like "vars/methodName.groovy", with a "call()" method in the code. This works ok, and I particularly note that "println" calls in these methods are seen in the Jenkins console output.

然后我决定要在方法调用之间保存一些状态,所以我在vars"中添加了一个名为uslutils.groovy"的新文件,其开头如下(减去一些必需的导入):

I then decided I wanted to save some state between method calls, so I added a new file in "vars" named "uslutils.groovy" that begins like this (minus some required imports):

class uslutils implements Serializable {

我定义了一些with<property>"方法来设置一个属性并返回它.

I defined some "with<property>" methods that set a property and return this.

然后我在uslutils"中写了一个public String toString()"方法,看起来像这样:

I then wrote a "public String toString()" method in "uslutils" that looks something like this:

public String toString() {
    println "Inside uslutils.toString()."
    return "[currentBuild[${currentBuild}] mechIdCredentials[${mechIdCredentials}] " +
           "baseStashURL[${baseStashURL}] jobName[${jobName}] codeBranch[${codeBranch}] " +
           "buildURL[${buildURL}] pullRequestURL[${pullRequestURL}] qBotUserID[${qBotUserID}] " +
           "qBotPassword[${qBotPassword}]]"
}

然后,在我的 Jenkinsfile 中,设置 uslutils 属性后,我添加了这样的一行:

Then, inside my Jenkinsfile, after setting the uslutils properties, I added a line like this:

println "uslutils[${uslutils}]"

然后,我开始我的工作,奇怪的是我没有看到uslutils"这一行,也没有看到 Inside uslutils.toString().线.但是,我确实修改了迄今为止添加的一个功能方法到uslutils"(除了with"方法),它返回一个字符串值,我只是在该值中添加了一个x".我的 Jenkinsfile 正在打印结果,它确实显示了额外的x".

Then, I ran my job, and the curious thing that happened is that I didn't see the "uslutils" line, or the Inside uslutils.toString(). line. However, I did modify the one functional method I've added so far to "uslutils" (besides the "with" methods), which returns a string value, and I just added an "x" to the value. My Jenkinsfile was printing the result from that, and it did show the additional "x".

请注意,这里没有发生错误,它似乎只是省略了共享库类中的 println 输出,甚至更奇怪的是,省略了 println 调用的输出在隐式调用 uslutils.toString() 方法的 Jenkinsfile 中.请注意,在控制台输出中可以看到原始 call() 方法中的 println 调用.

Note that no errors occurred here, it just seemed to omit the println output from within the shared library class, and even stranger, omitted the output from the println call in the Jenkinsfile that was implicitly calling the uslutils.toString() method. Note that the println calls in the original call() methods WERE seen in the console output.

您有什么想法吗?

更新:

我的 Jenkinsfile(以及其他)中现在有以下几行:

I now have the following lines in my Jenkinsfile (among others):

println "uslutils.qBotPassword[${uslutils.qBotPassword}]"
println "uslutils[${uslutils}]"
println "uslutils.toString()[${uslutils.toString()}]"

重复一遍,这里是uslutils.toString()"方法:

And to repeat, here is the "uslutils.toString()" method:

public String toString() {
    println "Inside uslutils.toString()."
    return "[currentBuild[${currentBuild}] mechIdCredentials[${mechIdCredentials}] " +
           "baseStashURL[${baseStashURL}] jobName[${jobName}] codeBranch[${codeBranch}] " +
           "codeURL[${codeURL}] buildURL[${buildURL}] pullRequestURL[${pullRequestURL}] qBotUserID[${qBotUserID}] " +
           "qBotPassword[${qBotPassword}]]"
}

以下是构建的相应输出行:

Here are corresponding lines of output from the build:

[Pipeline] echo
uslutils.qBotPassword[...]
[Pipeline] echo
uslutils.toString()[[currentBuild[org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper@41fb2c94] mechIdCredentials[121447d5-0fe4-470d-b785-6ce88225ef01] baseStashURL[https://...] jobName[unified-service-layer-build-pipeline] codeBranch[master] codeURL[ssh://git@...] buildURL[http://...] pullRequestURL[] qBotUserID[...] qBotPassword[...]]

如您所见,尝试 print "uslutils[${uslutils}]" 的行被简单地忽略了.尝试 print "uslutils.toString()[${uslutils.toString()}]" 的行确实渲染了,但还要注意 Inside uslutils.toString().没有渲染.

As you can see, the line attempting to print "uslutils[${uslutils}]" was simply ignored. The line attempting to print "uslutils.toString()[${uslutils.toString()}]" did render, but also note that the Inside uslutils.toString(). did not render.

我仍在寻找这种行为的解释,但也许这可以更简洁地总结它.

I'm still looking for an explanation for this behavior, but perhaps this summarizes it more succinctly.

推荐答案

我做了一些挖掘,发现了这个问题,https://issues.jenkins-ci.org/browse/JENKINS-41953,基本上在普通管道脚本中 println 被别名为 echo 步骤.但是当你在课堂上时,例如在管道 CPS 之外,则 echo 步骤不可用并且 println 被忽略(因为据我了解,没有可用的记录器).

I did some digging and found this issue, https://issues.jenkins-ci.org/browse/JENKINS-41953, basically in normal pipeline script println is aliased to echo step. But when you're in a class, e.g. outside of the pipeline CPS, then the echo step isn't available and the println is ignored (since, as I understand it, there is no logger available).

您可以做的是使用变量将脚本环境传播到您的类方法中,并通过变量调用 echo (在这个线程中找到了解决方案).像这样:

What you can do is to propagate the script environment into your class methods using a variable and call echo through the variable (found solution in this thread). Like this:

class A {
    Script script;
    public void a() {
        script.echo("Hello")
    }
}
def a = new A(script:this)
echo "Calling A.a()"
a.a()

输出:

Started by user jon
[Pipeline] echo
Calling A.a()
[Pipeline] echo
Hello
[Pipeline] End of Pipeline
Finished: SUCCESS

这是我们想要的.为了比较,这里没有传播:

Which is what we want. For comparison, here is without propagation:

class A {
    public void a() {
        println "Hello"
    }
}
def a = new A()
echo "Calling A.a()"
a.a()

给予:

Started by user jon
[Pipeline] echo
Calling A.a()
[Pipeline] End of Pipeline
Finished: SUCCESS

这篇关于println 在“调用"中“vars/foo.groovy"的方法;有效,但不在课堂上的方法中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆