在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")

我正在尝试编写一个Jenkins Job DSL脚本,并希望尽可能以声明/干巴巴的方式编写它。Jenkins任务通过多作业调用其他一些任务。我的Groovy最初看起来是这样的(所有内容都包含在一个类中,因为它在其他地方被引用):

我想抽象出就业创造,其中包含大量重复。我最后遇到了这样一件奇怪的事情:

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')
  }
}