Groovy с методом в конвейере DSL - PullRequest
1 голос
/ 23 сентября 2019

У нас есть несколько классов в общей библиотеке, где мы должны получить доступ к шагам конвейера, используя объект DSL, поэтому я подумал, что он будет работать с кодом ниже:

Версия 1

class T {
    def dsl

    def T(def dsl) {
        this.dsl = dsl
    }

    def F() {
        this.dsl.with {
            echo "Hello World"
        }
    }
}

new T(this).F()

Тем не менее, он генерирует следующее исключение безопасности скрипта:

Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (T echo java.lang.String). Administrators can decide whether to approve or reject this signature.
[Pipeline] End of Pipeline
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (T echo java.lang.String)

Похоже, dsl.with { echo ... } не переводится в dsl.echo и вместо этого приводит к поиску echo метод по class T.Предполагая, что это какая-то проблема с делегатом замыкания, я попробовал следующее, и оно все еще не работало (та же ошибка, что и выше):

Версия 2

def withDsl(def body) {
    body.delegate = this
    this.with body
}

class T {
    def dsl

    def T(def dsl) {
        this.dsl = dsl
    }

    def F() {
        dsl.withDsl {
            echo "Hello World"
        }
    }
}

new T(this).F()

Наконец-то это сработало, когда я создал оболочку поверх DSL и создал методы, которые просто делегировали вызовы DSL.Мне также пришлось изменить делегат замыкания, чтобы он работал:

Версия 3

class MyDsl {
    def dsl

    def MyDsl(def dsl) {
        this.dsl = dsl
    }

    def echo(msg) {
        dsl.echo msg        
    }
}

def withDsl(def body) {
    def mydsl = new MyDsl(this)
    body.delegate = mydsl
    mydsl.with body
}

class T {
    def dsl

    def T(def dsl) {
        this.dsl = dsl
    }

    def F() {
        dsl.withDsl {
            echo "Hello World"
        }
    }
}

new T(this).F()

Кто-нибудь может объяснить, почему первые две версии не будут работать?Есть ли что-то, что я могу сделать, чтобы избежать создания класса-обертки (что было бы больно)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...