List in place sorting in Jenkins Pipelines
我正在尝试对 Jenkins 管道中的对象列表进行排序。我在以下本地或 Jenkins 中运行代码得到了不同的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| pipeline {
agent any
stages {
stage ('default'){
steps {
script {
@NonCPS
def nonCpsTest = {
def list = [
['CreationDate': '200'],
['CreationDate': '300'],
['CreationDate': '100'],
]
def rval = list. sort { it ['CreationDate'] }
echo "Rval=$rval"
echo "List=$list"
}
nonCpsTest ()
}
}
}
}
} |
当我使用 groovy shell (groovysh) 在本地执行这个脚本时,结果是
1 2 3 4 5 6 7 8
| groovy:000 > list = [[ 'CreationDate': 200 ], [ 'CreationDate': 300 ], [ 'CreationDate': 100 ]]
===> [[CreationDate: 200], [CreationDate: 300], [CreationDate: 100]]
groovy:000 > rval = list. sort { it ['CreationDate'] }
===> [[CreationDate: 100], [CreationDate: 200], [CreationDate: 300]]
groovy:000 > list
===> [[CreationDate: 100], [CreationDate: 200], [CreationDate: 300]]
groovy:000 > list == rval
===> true |
在 Jenkins 服务器上我正在关注
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [Pipeline ] {
[Pipeline ] stage
[Pipeline ] { (default)
[Pipeline ] script
[Pipeline ] {
[Pipeline ] echo
Rval =300
[Pipeline ] echo
List=[[CreationDate: 200], [CreationDate: 300], [CreationDate: 100]]
[Pipeline ] }
[Pipeline ] // script
[Pipeline ] }
[Pipeline ] // stage
[Pipeline ] }
[Pipeline ] // node
[Pipeline ] End of Pipeline |
Jenkins 工作流是否使列表不可变,或者覆盖 sort 方法,如果是,如何在 Jenkins 管道代码中进行就地列表排序?
- 您应该可以使用 rval ,对吧?
-
我试图在列表中提取最年轻的元素,作为具有"最高"日期的元素。 Rval 仅用于调试目的,在 Jenkins 和控制台中显示不同的行为。
-
@toske 您来自 Jenkins 服务器的输出指向这部分代码 echo"List=$list" 您正在显示未排序的初始列表(排序不会改变输入列表,但会返回一个新的排序列表)。 rval 保存这个新的排序列表。
-
@SzymonStepniak 我已更新问题以显示 Jenkins 运行和控制台的完整输出。默认情况下,.sort 方法应该进行就地排序,并返回指向同一个数组的指针(从上面的 shell 中可以看到)。但是,在 Jenkins 中运行并非如此。如果您看上面,您会看到 sort 方法返回自然排序列表中的最后一项,并且列表未排序 - 但是来自 shell 的示例表明 .sort() 确实改变了列表。
-
@toske 是的,您对 .sort 和就地排序是正确的。这是违反直觉的。当你运行 def rval = list.sort(true) { it['CreationDate'] } 强制突变时会发生什么?您还可以在 Jenkins 中运行时仔细检查 list 变量的类型 - 自动突变仅发生在 list 上。
-
@SzymonStepniak 使用 def rval = list.sort true, { it['CreationDate'] } 运行会导致相同的行为。我也试过使用 java.util.Collections.sort() 没有运气。
-
@toske 一件更有趣的事情 - 请注意 rval 显示 300 而不是排序列表。这很奇怪。看起来这个问题仍然存在 - issues.jenkins-ci.org/browse/JENKINS-44924
-
您能否尝试按以下方式进行排序:def rval = list.sort { e -> e['CreationDate'] }?假设闭包可能会出现混乱。
您将 nonCpsTest 声明为变量并且它引用闭包的问题,??因此 @NonCPS 在这种情况下不起作用
以下变体可以正常工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @NonCPS
def nonCpsTest () {
def list = [
['CreationDate': '200'],
['CreationDate': '300'],
['CreationDate': '100'],
]
def rval = list. sort{ it ['CreationDate'] }
echo "Rval=$rval"
echo "List=$list"
}
node {
nonCpsTest ()
} |
- 谢谢,这可以通过一些修改使其成为声明性管道代码-gist.github.com/toshke/c22e5b924f061cb067ae895accb0da32