如何在groovy中从模板映射创建多个实例

时间:2017-10-17 12:08:26

标签: variables jenkins groovy scope

对于我的jenkins管道中的内部状态记录,我创建了一个“模板地图,我希望在多个阶段中使用它们并行运行

def status= [
    a : '',
    b: [
            b1: '',
            b2: '',
            b3: ''
      ],
    c: [ 
        c1: '',
        c2 : ''
    ]
]

这个状态模板我想传递给多个并行运行的函数/执行器。在并行分支内部,我想独立修改状态。请参阅以下最小示例

def status= [
    a : '',
    b: [
        b1: '',
        b2: '',
        b3: ''
    ],
    c: [
        c1: '',
        c2 : ''
    ]
]

def label1 = "windows"
def label2 = ''


parallel firstBranch: {
        run_node(label1, status)
    }, secondBranch: {
        run_node(label2, status)
    },
    failFast: true|false

def run_node (label, status){
    node(label) {
        status.b.b1 = env.NODE_NAME +"_"+ env.EXECUTOR_NUMBER
        sleep(1)
        echo "env.NODE_NAME_env.EXECUTOR_NUMBER: ${status.b.b1}"  
        // expected: env.NODE_NAME_env.EXECUTOR_NUMBER
        this.a_function(status)
        echo "env.NODE_NAME_env.EXECUTOR_NUMBER: ${status.b.b1}"  
        // expected(still): env.NODE_NAME_env.EXECUTOR_NUMBER (off current node)
        // is: env.NODE_NAME_env.EXECUTOR_NUMBERmore Info AND probably from the wrong node
    }
}

def a_function(status){
     status.b.b1 += "more Info"
     echo "env.NODE_NAME_env.EXECUTOR_NUMBERmore Info: ${status.b.b1}" 
     // expected: env.NODE_NAME_env.EXECUTOR_NUMBERmore Info
     sleep(0.5)
     echo "env.NODE_NAME_env.EXECUTOR_NUMBERmore Info: ${status.b.b1}" 
     // expected: env.NODE_NAME_env.EXECUTOR_NUMBERmore Info
}

结果是

  

[firstBranch] env.NODE_NAME_env.EXECUTOR_NUMBER:   LR-Z4933-39110bdb_0

     

[firstBranch] env.NODE_NAME_env.EXECUTOR_NUMBER更多信息:   LR-Z4933-39110bdb_0more信息

     

[firstBranch] env.NODE_NAME_env.EXECUTOR_NUMBER>更多信息:   LR-Z4933-39110bdb_0more信息

     

[firstBranch] env.NODE_NAME_env.EXECUTOR_NUMBER:   LR-Z4933-39110bdb_0more信息

     

[secondBranch] env.NODE_NAME_env.EXECUTOR_NUMBER:   LR-Z4933-39110bdb_0more信息

     

[secondBranch] env.NODE_NAME_env.EXECUTOR_NUMBER更多信息:   LR-Z4933-39110bdb_0more Infomore Info

     

[secondBranch] env.NODE_NAME_env.EXECUTOR_NUMBER更多信息:   LR-Z4933-39110bdb_0more Infomore Info

     

[secondBranch] env.NODE_NAME_env.EXECUTOR_NUMBER:   LR-Z4933-39110bdb_0more Infomore Info

请注意,第一个分支中的状态会被第二个分支覆盖,反之亦然。

如何在将thm作为参数传递给函数时实现独立的状态变量

2 个答案:

答案 0 :(得分:0)

您可以定义模板地图。当您需要多个相同的实例时,您可能希望使用克隆的模板映射对每个实例进行不同的修改。

以下是显示示例的简短代码段。

def template = [a: '', b: '']
def instancea = template.clone()
def instanceb = template.clone()
def instancec = template.clone()
instancea.a = 'testa'
instanceb.a = 'testb'
instancec.a = 'testc'
println instancea
println instanceb
println instancec

当然,你可以加入更大的地图,上面只是为了演示。

答案 1 :(得分:0)

您通过引用传递status函数。但即使你做status.clone(),我也怀疑这不是status的深层副本。 status.b可能仍然指向相同的参考。您需要制作status的深层副本,并将该深层副本发送给该函数。

我不确定框架地图的深层副本是否是正确的方法。您可以发送一个空地图[:],然后让被调用的函数将这些部分添加到他们需要的地图中。如果您确实需要预先定义地图的内容,那么我认为您应该添加一个类并从该类创建新对象。