Как разобрать Jenkinsfile из кода Groovy

У меня есть Jenkinsfile с некоторыми свойствами, например

trace = false

userNotifications = [
    build_master :                 [name : 'name',
                                    email : 'email',
                                    slackid: 'slack id',
                                    slackchannel: 'slack channel']
]
env.aProperty = "aValue"
node('COMPILE')
{
...
}

Я хочу проанализировать приведенный выше файл Jenkinsfile внутри отличного кода, чтобы получить доступ к некоторым значениям свойств.

Когда я использую GroovyShell вот так

        Binding binding = new Binding()
        GroovyShell shell = new GroovyShell(binding)
        Object groovyDsl = shell.evaluate(clean)

я получаю эту ошибку

groovy.lang.MissingMethodException: No signature of method: Script1.node() is applicable for argument types: (String, Script1$_run_closure1) values: [COMPILE, Script1$_run_closure1@7d804e7]

Я мог бы обойти конкретную ошибку с помощью некоторого метапрограммирования Groovy, однако я не уверен, что это правильное направление. Мой вопрос: как лучше всего проанализировать Jenkinsfile в коде Groovy? В конце концов, это Groovy DSL, и я ожидаю, что он будет более простым.


person Georgios F.    schedule 17.06.2020    source источник


Ответы (2)


DSL зависят от контекста и не могут быть запущены вне контекста.

ты можешь попробовать

  • Консоль сценариев в разделе «Управление Дженкинсом».
person HumayunM    schedule 17.06.2020
comment
Извините, что не пояснил это раньше, но я не использую Jenkins. Все, что я хочу сделать, это просто извлечь некоторые свойства из Jenkinsfile из автономного сценария Groovy. - person Georgios F.; 17.06.2020

Вот как я в итоге сделал то, что хотел:

import org.codehaus.groovy.control.CompilerConfiguration

class JenkinsfileParser {
    static void main(String[] args) {
        LinkedHashMap vars = JenkinsfileParser.parse('Jenkinsfile' as File)
        println vars.toString()
    }

    static LinkedHashMap parse(File jenkinsfile) {
        CompilerConfiguration config = new CompilerConfiguration()
        config.scriptBaseClass = JenkinsfileBaseClass.class.name
        Binding binding = new Binding()
        GroovyShell shell = new GroovyShell(this.class.classLoader, binding, config)
        String clean = jenkinsfile.text.replace('import hudson.model.*', '')
                .replace('import hudson.EnvVars', '')
        Script script = shell.parse(clean)
        script.run()
        return binding.variables
    }

    static abstract class JenkinsfileBaseClass extends Script {
        LinkedHashMap<String, Closure> nodeClosures = new LinkedHashMap<>()
        LinkedHashMap env = new LinkedHashMap()
        CurrentBuild currentBuild = new CurrentBuild()
        LinkedHashMap parallelClosures = new LinkedHashMap<>()

        void node(String name, Closure closure) {
            nodeClosures.put(name, closure)
        }

        void parallel(LinkedHashMap closures) {
            parallelClosures.putAll(closures)
        }

        class CurrentBuild {
            List<String> expectedResults = new ArrayList<>()

            boolean resultIsBetterOrEqualTo(String expected) {
                expectedResults << expected
                return true
            }
        }
    }
}

JenkinsfileBaseClass специфичен для моего Jenkinsfile и потребует адаптации для другого Jenkinsfile.

Соответствующую документацию можно найти здесь: https://groovy-lang.org/integrating.html

Я попытался использовать пакет implementation group: 'org.jenkins-ci.main', name: 'jenkins-core', version: '2.9' из репозитория maven http://repo.jenkins-ci.org/public/, однако, похоже, там нет ничего полезного для моего случая.

Дайте мне знать, если есть лучший или более элегантный способ сделать это.

person Georgios F.    schedule 17.06.2020