按照此处的链接,我们有自己的 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
要使用
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 脚本安全性允许的范围内。