Groovy:如何从另一个闭包中调用顶级范围内的闭包

Ako*_*kom 2 groovy closures jenkins jenkins-job-dsl

我正在尝试将利用Jenkins Job DSL插件的代码分解为可重用的部分,并且我怀疑我的问题是Groovy的通用问题,而不是Jenkins特定的问题。例如,我想重用此块的某些部分:

freeStyleJob() {
    //generic stuff
    name "something"
    description "something else"

    //custom stuff
    scm {
       svn {
           //etc....
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

通过将名称和描述放在实用程序方法中(显然,我不仅想在现实生活中做更多的事情)。但是,我找不到合适的语法来创建当前作用域的闭包。这是我认为的样子:

def jobCommonItems() {
    return {
        //generic stuff
        name "something"
        description "something else"
    }
}


freeStyleJob() {
    jobCommonItems().call()

    //custom stuff
    scm {
       svn {
           //etc....
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

(也许有一个closure.delegate =这个在某处)

但是,这不适用于闭包。它适用于方法,如下所示:https : //dzone.com/articles/groovy-closures-owner-delegate

为了说明这一点,下面的测试显示了三种可能的语法组合:

String myString = "Top Level: string"
def myMethod() {
    println "Top Level: Method"
}
def myClosure = { println "Top Level: Class"}

class MyClass1 {
    String myString = "Class1: String"
    def myMethod() {
        println "Class1: Method"
    }
    def myClosure = { println "Class1: Closure"}
}

class MyClass2 {
    String myString = "Class2: String"
    def myMethod() {
        println "Class2: Method"
    }
    def myClosure = { println "Class2: Closure"}
}

class MyClass {
    def closure = {
        println "In-Class generated closure begins, delegate is ${delegate}"
        myMethod()
        myClosure()
        println myString
    }
}

def closure = new MyClass().closure
closure.delegate = new MyClass1()
closure()

closure = new MyClass().closure
closure.delegate = new MyClass2()
closure()

// This fails - it can find the top level method, but not closure or string
closure.delegate = this
closure()



def methodMissing(String methodName, args) {
    println "Method not found in class ${this} by name ${methodName}"
}
Run Code Online (Sandbox Code Playgroud)

我收到一个错误,指出闭包不在主类中(即测试test.groovy):在类test @ 60611244中找不到名为myClosure的方法

我尝试将委托更改为“ this”,尝试更改查找策略,等等。我可能缺少一些基本知识。

das*_*ker 5

作业工厂方法(如freeStyleJob返回一个对象)可以使用该with方法来应用更多配置。该方法需要一个闭包参数,该参数与传递给该freeStyleJob方法的闭包具有相同的属性。

def basicConfiguration() {
    return {
        description('foo')
        scm {
            // whatever
        }
    }
}

def myJob = freeStyleJob('example') {
    publishers {
        // more config
    }
}
myJob.with basicConfiguration()
Run Code Online (Sandbox Code Playgroud)

脚本本身就是一个实例,DslFactory该实例是包含例如freeStyleJob方法的接口。您可以将该对象传递给类或方法以使用freeStyleJob。

def myJobFactory(def dslFactory, def jobName) {
    dslFactory.freeStyleJob(jobName) {
        description('foo')
    }
}

def myJob = myJobFactory(this, 'example')
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用myJob对象使用对象应用进一步的配置with。