我想为我的Jenkins构建加载一个闭包,但是将一些对我们系统上正在进行的任何类型的构建(Go,Java,Docker)通用的变量传递给它。由于我是从单独的Groovy文件加载特定的闭包,因此看不到这些变量。为了使示例更简单,我注释掉了负载并包含了该闭包。
我不确定如何执行此操作-如何将配置从buildProject传递到buildSpecificProject?我说错了吗?
#!/usr/bin/groovy
//def buildSpecificProject = load 'buildSpecificProject.groovy'
def buildSpecificProject = { body->
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()
println config.name
println config.builddirectory
}
def buildProject = { projbody ->
def config = [:]
projbody.resolveStrategy = Closure.DELEGATE_FIRST
projbody.delegate = config
projbody()
config.builddirectory = "/bar"
return config
}
try {
def newProjectVersion = buildSpecificProject { body ->
buildProject { projbody ->
name = 'projectname'
versionPrefix = "4.2.0"
fetchFromURL = 'git@github.com:myorg/myproject.git'
}
}
println "New Project Version = ${newProjectVersion}\n"
} catch (err) {
println err
}
答案 0 :(得分:1)
我真的没有在Jenkins中构建脚本的经验,所以也许我的答案不适用,但是从Groovy的角度来看,情况如下:
buildSpecificProject中的config变量是一个本地变量,除非您公开它或其值,否则您将无法访问该变量。现在,您可以通过实际设置委托来做到这一点。
如果我们说buildProject仅从给buildSpecificProject的块中调用,则给buildProject的块是嵌套在给buildSpecificProject的Closure中的Closure。此Closure对象将具有属性所有者,在这种情况下,该属性所有者将引用封闭的Closure实例(请参见http://groovy-lang.org/closures.html#_owner_of_a_closure)。我们知道其中已将配置设置为委托,因此您可以执行projbody.owner.delegate来访问buildSpecificProject设置的配置。
但是实际上我会考虑做这样的事情:
def buildSpecificProject = { body ->
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = [config: config] // expose config
body()
println config.name
println config.builddirectory
return config
}
def buildProject = { config, projbody ->
projbody()
config.builddirectory = "/bar"
}
try {
def newProjectVersion = buildSpecificProject { body ->
// make config accessible to buildProject by providing it as parameter
buildProject(config) { projbody ->
config.name = 'projectname'
config.versionPrefix = "4.2.0"
config.fetchFromURL = 'git@github.com:myorg/myproject.git'
}
}
println "New Project Version = ${newProjectVersion}\n"
} catch (err) {
println err
}
如您所见,buildSpecificProject实际上足以设置委托,我使用一个名为config的键将其设置为包含实际配置的映射。缺点当然是您现在必须执行config.name。还要注意调用“ buildProject(config){projbody->”,该调用将配置传递给buildProject。当然,我们可以将两种想法结合起来:
def buildSpecificProject = { body ->
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()
println config.name
println config.builddirectory
return config
}
def buildProject = { config, projbody ->
projbody()
config.builddirectory = "/bar"
}
try {
def newProjectVersion = buildSpecificProject {
buildProject(delegate) { projbody ->
name = 'projectname'
versionPrefix = "4.2.0"
fetchFromURL = 'git@github.com:myorg/myproject.git'
}
}
println "New Project Version = ${newProjectVersion}\n"
} catch (err) {
println err
}
但是我不建议这样做,因为我不希望以这种方式依赖委托。我很容易摔坏。