Impossibility to iterate over a Map using Groovy within Jenkins Pipeline

后端 未结 2 1892
暗喜
暗喜 2020-12-29 23:49

We are trying to iterate over a Map, but without any success. We reduced our issue to this minimal example:

def map = [
           \'monday\': \         


        
相关标签:
2条回答
  • 2020-12-30 00:41

    Its been some time since I played with this, but the best way to iterate through maps (and other containers) was with "classical" for loops, or the "for in". See Bug: Mishandling of binary methods accepting Closure

    To your specific problem, most (all?) pipeline DSL commands will add a sequence point, with that I mean its possible to save the state of the pipeline and resume it at a later time. Think of waiting for user input for example, you want to keep this state even through a restart. The result is that every live instance has to be serialized - but the standard Map iterator is unfortunately not serializable. Original Thread

    The best solution I can come up with is defining a Function to convert a Map into a list of serializable MapEntries. The function is not using any pipeline steps, so nothing has to be serializable within it.

    @NonCPS
    def mapToList(depmap) {
        def dlist = []
        for (def entry2 in depmap) {
            dlist.add(new java.util.AbstractMap.SimpleImmutableEntry(entry2.key, entry2.value))
        }
        dlist
    }
    

    This has to be obviously called for each map you want to iterate, but the upside it, that the body of the loop stays the same.

    for (def e in mapToList(map))
    {
        println "key = ${e.key}, value = ${e.value}"
    }
    

    You will have to approve the SimpleImmutableEntry constructor the first time, or quite possibly you could work around that by placing the mapToList function in the workflow library.

    0 讨论(0)
  • 2020-12-30 00:44

    Or much simpler

    for (def key in map.keySet()) {
      println "key = ${key}, value = ${map[key]}"
    }
    
    0 讨论(0)
提交回复
热议问题