在Groovy中从委托范围获取变量
我正在尝试编写一个Jenkins Job DSL脚本,并希望尽可能以声明/干巴巴的方式编写它。Jenkins任务通过多作业调用其他一些任务。我的Groovy最初看起来是这样的(所有内容都包含在一个类中,因为它在其他地方被引用): 我想抽象出就业创造,其中包含大量重复。我最后遇到了这样一件奇怪的事情:在Groovy中从委托范围获取变量,groovy,jenkins,jenkins-job-dsl,Groovy,Jenkins,Jenkins Job Dsl,我正在尝试编写一个Jenkins Job DSL脚本,并希望尽可能以声明/干巴巴的方式编写它。Jenkins任务通过多作业调用其他一些任务。我的Groovy最初看起来是这样的(所有内容都包含在一个类中,因为它在其他地方被引用): 我想抽象出就业创造,其中包含大量重复。我最后遇到了这样一件奇怪的事情: static void buildDownstream(def parentJob, String commit_a="master", String commit_b="master")
static void buildDownstream(def parentJob, String commit_a="master",
String commit_b="master") {
parentJob.with {
steps {
phase('Phase') {
def phase = ({ owner })();
{ ->
add_node_label=true;
{ ->
commit_a = null;
def self = ({ owner })();
addJob("name_1", self).call(phase);
}
def self = ({ owner })();
addJob("name_2", self).call(phase);
addJob("name_3", self).call(phase);
}
}
}
}
}
private static Closure addJob(String job_name, Closure callingClosure) {
return { phase ->
def job_config = {
if(commit_a != null) {
prop('COMMIT_A', commit_a)
}
if(commit_b != null) {
prop('COMMIT_B', commit_b)
}
if(add_node_label == true) {
nodeLabel('NODE_LABEL', NODE_LABEL_MAP[job_name])
}
killPhaseCondition('NEVER')
}
job_config.delegate = callingClosure
job_config.resolveStrategy = Closure.DELEGATE_ONLY
phase.job(job_name, job_config)
}
}
这可能是完全非惯用的Groovy(所有这些def self=({owner})(
的东西都不适合我),根本不起作用
基本上,我希望将callingClosure
范围中的所有变量传递给job\u config
闭包,而不将它们作为参数显式传递。(显式地传递参数映射是有效的,但是当有很多参数时,它会变得很笨拙。)我该怎么做
(注:目前,Groovy正试图将job\u config
中的commit\u a
变量解析为来自javaposse.jobdsl.dsl.helpers.step.PhaseContext
,我觉得很奇怪;我没有在PhaseContext
中显式地将委托设置为闭包吗?)
编辑:从中,我似乎可以设置
阶段
=委托
(默认为所有者
?),而不是({owner})(
),这样就可以了;我也没有真正理解这一点,因为job
是PhaseContext
的一个属性,而不是它的父对象(?)好吧,我没有试图要求Groovy隐式解析委托上下文中的变量,而是在映射中传递参数
static void buildDownstream(def parentJob,
String commit_a="master", String commit_b="master") {
parentJob.with {
steps {
phase('Tests') {
def params = [COMMIT_A:commit_a]
this.getTestJob(delegate, "name_1", params)
params.COMMIT_B = commit_b
this.getTestJob(delegate, "name_2", params)
this.getTestJob(delegate, "name_3", params)
continuationCondition('ALWAYS')
}
}
}
}
private static void getTestJob(def phase, String job_name,
Map properties) {
phase.job(job_name) {
properties.each { k, v -> prop(k, v) }
killPhaseCondition('NEVER')
}
}
我最初的方法的一个问题是,我试图访问闭包中的局部变量,但这需要对闭包进行评估;这真的很奇怪,我想我不应该这么做。如果你想访问变量,为什么不把闭包作为参数传递呢?闭包自然也可以访问其所有者变量。我刚刚发布了一个关于代表的问题,也许它对你有帮助:谢谢你的建议!最后我做了类似的事情(只是将所有参数作为映射传递)。
static void buildDownstream(def parentJob,
String commit_a="master", String commit_b="master") {
parentJob.with {
steps {
phase('Tests') {
def params = [COMMIT_A:commit_a]
this.getTestJob(delegate, "name_1", params)
params.COMMIT_B = commit_b
this.getTestJob(delegate, "name_2", params)
this.getTestJob(delegate, "name_3", params)
continuationCondition('ALWAYS')
}
}
}
}
private static void getTestJob(def phase, String job_name,
Map properties) {
phase.job(job_name) {
properties.each { k, v -> prop(k, v) }
killPhaseCondition('NEVER')
}
}