println在“通话”中“vars / foo.groovy”的方法工作,但不是在课堂上的方法 [英] println in "call" method of "vars/foo.groovy" works, but not in method in class

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

问题描述

我正在通过构建一个Jenkins管道共享库来进行迭代,所以我的Jenkinsfile稍微清洁一些。



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



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



然后我决定在方法调用之间保存一些状态,所以我在名为 uslutils.groovy / code>开始像这样(减去一些必需的导入):

  class uslutils implements Serializable {

我用< property> >方法定义了一些方法设置一个属性并返回这个。

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

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

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

  printlnuslutils [$ {uslutils}]

然后,我运行了我的工作,而发生的奇怪事情是我没有看到uslutils行或Ins​​ide uslutils.toString()。线。不过,我修改了迄今为止添加到uslutils(除了with方法)之外的一个函数方法,它返回一个字符串值,并且我只为该值添加了一个x。我的Jenkinsfile正在打印结果,它显示了额外的x。



请注意,这里没有发生任何错误,它似乎忽略了println从共享库类中输出,甚至是陌生人,在Jenkinsfile中隐藏了调用 uslutils.toString()方法的println调用的输出。请注意,在控制台输出中看到的原始 call()方法中的 println 调用。



有什么想法可能发生在这里?

更新



我现在在我的Jenkinsfile中有以下几行(其中包括):

  printlnuslutils .qBotPassword [$ {uslutils.qBotPassword}]
printlnuslutils [$ {uslutils}]
printlnuslutils.toString()[$ {uslutils.toString()}]

再说一遍,这里是uslutils.toString()方法:

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

$ / code>

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

  [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 [统一服务[...] layer_build-pipeline] codeBranch [master] codeURL [ssh:// git @ ...] buildURL [http:// ...] pullRequestURL [] qBotUserID [...] qBotPassword [...]]

正如您所看到的,试图打印uslutils [$ {us lutils}]简直被忽略。试图打印uslutils.toString()[$ {uslutils.toString()}]的行确实​​进行了渲染,但也要注意Inside uslutils.toString()。没有呈现。



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

解决方案

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

您可以使用变量将脚本环境传播到您的类方法中,并通过 echo 变量(在此主题中找到解决方案)。像这样:

  class A {
脚本脚本;
public void a(){
script.echo(Hello)
}
}
def a = new A(script:this)
echoCalling Aa()
aa()

输出:

 由用户jon 
开始[Pipeline] echo
调用Aa()
[Pipeline] echo
你好
[Pipeline]管道终止
完成:SUCCESS

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

  class A {
public void a(){
println 你好
}
}
def a = new A()
echoCalling Aa()
aa()


$ b

给出:

 由用户启动jon 
[Pipeline] echo
调用Aa()
[Pipeline]流水线结束
完成:SUCCESS


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

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

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.

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 {

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

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}]]"
}

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

    println "uslutils[${uslutils}]"

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".

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.

Any ideas what might be happening here?

Update:

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

println "uslutils.qBotPassword[${uslutils.qBotPassword}]"
println "uslutils[${uslutils}]"
println "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[...]]

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.

解决方案

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).

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()

outputs:

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()

Gives:

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

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

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