从 Groovy 中的委托范围获取变量
Get variables from delegate scope in Groovy
我正在尝试编写 Jenkins Job DSL 脚本,并希望尽可能以声明方式/DRY 方式编写它。 Jenkins 任务通过 MultiJob 调用其他一些任务。我有 Groovy 最初看起来像这样(所有内容都包含在 class 中,因为它在其他地方被引用):
static void buildDownstream(def parentJob, String commit_a="master",
String commit_b="master") {
parentJob.with {
steps {
phase('Phase') {
job("name_1") {
prop('COMMIT_A', commit_a)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_1"])
killPhaseCondition('NEVER')
}
job("name_2") {
prop('COMMIT_A', commit_a)
prop('COMMIT_B', commit_b)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_2"])
killPhaseCondition('NEVER')
}
job("name_3") {
prop('COMMIT_A', commit_a)
prop('COMMIT_B', commit_b)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_3"])
killPhaseCondition('NEVER')
}
}
}
}
}
我想抽象出创造就业机会,其中包含很多重复。我最终得到了这样奇怪的东西:
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_config
闭包,而不是将它们全部作为参数显式传递。 (显式传递参数映射是可行的,但当有很多参数时它会变得笨拙。)我该怎么做?
(P.S:目前,Groovy 正在尝试将 job_config
中的 commit_a
变量解析为来自 javaposse.jobdsl.dsl.helpers.step.PhaseContext
,我觉得这很奇怪;我不是在 PhaseContext
中明确地将委托设置为闭包吗?)
编辑:从 看来,我可以设置 phase
= delegate
(默认为 owner
?)而不是 ({ 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')
}
}
我原来的方法的一个问题是我试图访问闭包中的局部变量,但这需要对闭包进行评估;结果真的很奇怪,我想我不应该尝试那样做。
我正在尝试编写 Jenkins Job DSL 脚本,并希望尽可能以声明方式/DRY 方式编写它。 Jenkins 任务通过 MultiJob 调用其他一些任务。我有 Groovy 最初看起来像这样(所有内容都包含在 class 中,因为它在其他地方被引用):
static void buildDownstream(def parentJob, String commit_a="master",
String commit_b="master") {
parentJob.with {
steps {
phase('Phase') {
job("name_1") {
prop('COMMIT_A', commit_a)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_1"])
killPhaseCondition('NEVER')
}
job("name_2") {
prop('COMMIT_A', commit_a)
prop('COMMIT_B', commit_b)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_2"])
killPhaseCondition('NEVER')
}
job("name_3") {
prop('COMMIT_A', commit_a)
prop('COMMIT_B', commit_b)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_3"])
killPhaseCondition('NEVER')
}
}
}
}
}
我想抽象出创造就业机会,其中包含很多重复。我最终得到了这样奇怪的东西:
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_config
闭包,而不是将它们全部作为参数显式传递。 (显式传递参数映射是可行的,但当有很多参数时它会变得笨拙。)我该怎么做?
(P.S:目前,Groovy 正在尝试将 job_config
中的 commit_a
变量解析为来自 javaposse.jobdsl.dsl.helpers.step.PhaseContext
,我觉得这很奇怪;我不是在 PhaseContext
中明确地将委托设置为闭包吗?)
编辑:从 phase
= delegate
(默认为 owner
?)而不是 ({ 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')
}
}
我原来的方法的一个问题是我试图访问闭包中的局部变量,但这需要对闭包进行评估;结果真的很奇怪,我想我不应该尝试那样做。