使用 Groovy 映射进行 DSL 参数

问题描述 投票:0回答:1

按照此处的链接,我们有自己的 DSL 扩展,它在文件中的定义如下

vars/buildFlow.groovy
:

Map<String, Object> mapFromClosure(Closure body) {
    Map<String, Object> config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config
    body()

    // other things
}

在我的

Jenkinsfile
中,我可以这样使用它:

buildFlow {
    // different args
}

我希望能够动态地将参数填充到

buildFlow
,但我不确定如何使用 Groovy 和闭包。根据我的条件,我想要的一切都有
Map
,但我不能像这样将
Map
传递给
buildFlow
。有没有办法将
Map
参数转换为闭包构造函数?

Map flowArgs = [
    argA: 1,
    argB: 2
]

buildFlow {
    flowArgs
}

我见过谈论使用

ConfigObject
的解决方案,但这受到限制:

Scripts not permitted to use new groovy.util.ConfigObject
jenkins groovy closures dsl
1个回答
0
投票

要使用

buildFlow
动态填充
Map
的参数,您可以考虑将
Map
转换为 Groovy 中的 closure
这可以通过迭代
Map
并将每个键值对作为属性应用到闭包来完成。

首先,修改

mapFromClosure
中的
vars/buildFlow.groovy
方法来处理
Closure
Map
类型:

Map<String, Object> mapFromClosure(Object body) {
    Map<String, Object> config = [:]

    if (body instanceof Closure) {
        body.resolveStrategy = Closure.DELEGATE_FIRST
        body.delegate = config
        body()
    } else if (body instanceof Map) {
        config.putAll(body)
    }

    // other things
    return config
}

然后,创建一个实用方法将

Map
转换为
Closure
(如“Groovy 在 Map 和 Closure 之间转换”):

Closure mapToClosure(Map map) {
    return {
        map.each { key, value ->
            delegate."$key" = value
        }
    }
}

Jenkinsfile
中使用此实用方法将
Map
转换为闭包,然后再将其传递给
buildFlow
:

Map flowArgs = [
    argA: 1,
    argB: 2
]

buildFlow mapToClosure(flowArgs)

结果:

Jenkinsfile
    |
    └── buildFlow (Accepts Closure or Map)
            |
            └── mapFromClosure (Handles both Closure and Map)
                    |
                    └── mapToClosure (Converts Map to Closure)

这将提供处理 DSL 中的闭包和映射的灵活性,允许动态参数传递到

buildFlow

mapToClosure
函数在 Jenkins 管道中用于将参数
Map
转换为
Closure
,然后再将其传递给
buildFlow
。这确保管道脚本保持在 Jenkins 脚本安全性允许的范围内。

© www.soinside.com 2019 - 2024. All rights reserved.