使用Groovy map作为DSL参数

xriantvc  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(137)

link here之后,我们有自己的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

2j4z5cfb

2j4z5cfb1#

要使用Map动态填充buildFlow的参数,可以考虑在Groovy中将Map转换为closure
这可以通过迭代Map并将每个键值对作为属性应用于闭包来完成。
首先,修改vars/buildFlow.groovy中的mapFromClosure方法以处理ClosureMap类型:

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 converting between Map and 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中处理闭包和Map的灵活性,允许将动态参数传递给buildFlow
在Jenkins管道中使用mapToClosure函数将Map参数转换为Closure,然后将其传递给buildFlow。这确保管道脚本保持在Jenkins脚本安全性允许的范围内。

相关问题