Groovy 在 Jenkins Workflow 脚本中收集返回的 GString
Groovy collect returning GString in a Jenkins Workflow script
好像在下面这段代码中:
def formattedPaths = affectedFiles.collect {
"${it.editType.name} ${it.path}"
}
至少有时 formattedPaths
求值为 GString 而不是 List。这段代码是一个更大的 Jenkins Workflow 脚本的片段,类似于:
node {
currentBuild.rawBuild.changeSets[0].collect {
"""<b>${it.user}</b> @ rev. ${it.revision}: ${it.msg}
${affectedFilesLog(it.affectedFiles)}"""
}
}
def affectedFilesLog(affectedFiles) {
println "Affected files [${affectedFiles.class}]: $affectedFiles"
def formattedPaths = affectedFiles.collect {
"${it.editType.name} ${it.path}"
}
println "formattedPaths [${formattedPaths.class}]: $formattedPaths"
formatItemList(formattedPaths)
}
def formatItemList(list) {
if (list) {
return list.join('\n')
}
return '(none)'
}
运行 Jenkins 中的这个脚本产生输出:
Running: Print Message
Affected files [class java.util.ArrayList]: [hudson.scm.SubversionChangeLogSet$Path@5030a7d8]
Running: Print Message
formattedPaths [class org.codehaus.groovy.runtime.GStringImpl]: edit my/path/flow.groovy
(...)
groovy.lang.MissingMethodException: No signature of method: java.lang.String.join() is applicable for argument types: (java.lang.String) values: [
]
这让我相信在代码中:
println "Affected files [${affectedFiles.class}]: $affectedFiles"
def formattedPaths = affectedFiles.collect {
"${it.editType.name} ${it.path}"
}
println "formattedPaths [${formattedPaths.class}]: $formattedPaths"
affectedFiles
是ArrayList
(输出中的脚本输出Affected files [class java.util.ArrayList]: [hudson.scm.SubversionChangeLogSet$Path@5030a7d8]
)
但是 运行 收集方法的结果 - 分配给 formattedPaths
- 是一个 GString(输出:formattedPaths [class org.codehaus.groovy.runtime.GStringImpl]: edit my/path/flow.groovy
)
collect 方法不应该总是 return 一个列表吗?
我猜你的代码不是线程安全的。如果您将一些对象作为参数传递给其他一些函数,请不要更改它。始终创建并 return 一个新的更改对象。不要操纵原始数据。您应该检查对象所在的位置。它只是在函数内部还是在全局范围内?
您目前无法使用 collect
方法。 JENKINS-26481
在评论中指出这可能是 Jenkins Workflow 插件造成的一些副作用后,我决定使用普通的 for-each 循环:
def affectedFilesLog(affectedFiles) {
println "Affected files [${affectedFiles.class}]: $affectedFiles"
def ret = ""
for (Object affectedFile : affectedFiles) {
ret += affectedFile.path + '\n'
}
println("affectedFilesLog ret [${ret.class}]: $ret")
if (!ret) {
return '(brak)'
}
return ret;
}
编辑 2015 年 11 月 19 日:
Jenkins 工作流插件错误处理采用闭包的函数,请参阅 https://issues.jenkins-ci.org/browse/JENKINS-26481 及其副本。因此,将代码重写为简单的 Java for-each 循环是最好的解决方案。
好像在下面这段代码中:
def formattedPaths = affectedFiles.collect {
"${it.editType.name} ${it.path}"
}
至少有时 formattedPaths
求值为 GString 而不是 List。这段代码是一个更大的 Jenkins Workflow 脚本的片段,类似于:
node {
currentBuild.rawBuild.changeSets[0].collect {
"""<b>${it.user}</b> @ rev. ${it.revision}: ${it.msg}
${affectedFilesLog(it.affectedFiles)}"""
}
}
def affectedFilesLog(affectedFiles) {
println "Affected files [${affectedFiles.class}]: $affectedFiles"
def formattedPaths = affectedFiles.collect {
"${it.editType.name} ${it.path}"
}
println "formattedPaths [${formattedPaths.class}]: $formattedPaths"
formatItemList(formattedPaths)
}
def formatItemList(list) {
if (list) {
return list.join('\n')
}
return '(none)'
}
运行 Jenkins 中的这个脚本产生输出:
Running: Print Message
Affected files [class java.util.ArrayList]: [hudson.scm.SubversionChangeLogSet$Path@5030a7d8]
Running: Print Message
formattedPaths [class org.codehaus.groovy.runtime.GStringImpl]: edit my/path/flow.groovy
(...)
groovy.lang.MissingMethodException: No signature of method: java.lang.String.join() is applicable for argument types: (java.lang.String) values: [
]
这让我相信在代码中:
println "Affected files [${affectedFiles.class}]: $affectedFiles"
def formattedPaths = affectedFiles.collect {
"${it.editType.name} ${it.path}"
}
println "formattedPaths [${formattedPaths.class}]: $formattedPaths"
affectedFiles
是ArrayList
(输出中的脚本输出Affected files [class java.util.ArrayList]: [hudson.scm.SubversionChangeLogSet$Path@5030a7d8]
)
但是 运行 收集方法的结果 - 分配给 formattedPaths
- 是一个 GString(输出:formattedPaths [class org.codehaus.groovy.runtime.GStringImpl]: edit my/path/flow.groovy
)
collect 方法不应该总是 return 一个列表吗?
我猜你的代码不是线程安全的。如果您将一些对象作为参数传递给其他一些函数,请不要更改它。始终创建并 return 一个新的更改对象。不要操纵原始数据。您应该检查对象所在的位置。它只是在函数内部还是在全局范围内?
您目前无法使用 collect
方法。 JENKINS-26481
在评论中指出这可能是 Jenkins Workflow 插件造成的一些副作用后,我决定使用普通的 for-each 循环:
def affectedFilesLog(affectedFiles) {
println "Affected files [${affectedFiles.class}]: $affectedFiles"
def ret = ""
for (Object affectedFile : affectedFiles) {
ret += affectedFile.path + '\n'
}
println("affectedFilesLog ret [${ret.class}]: $ret")
if (!ret) {
return '(brak)'
}
return ret;
}
编辑 2015 年 11 月 19 日: Jenkins 工作流插件错误处理采用闭包的函数,请参阅 https://issues.jenkins-ci.org/browse/JENKINS-26481 及其副本。因此,将代码重写为简单的 Java for-each 循环是最好的解决方案。