【问题标题】:How to extract pipeline dsl in the pipeline plugin with the Java?如何使用Java在管道插件中提取管道dsl?
【发布时间】:2021-09-24 05:02:42
【问题描述】:

我正在为 CNB(buildpacks)开发一个 Jenkins 管道插件。需要用Java获取流水线脚本中的变量但是还是不能成功。

这是我的管道脚本。

buildpacks {
    builder = "some/builder"
}

并且我可以在 buildpacks.groovy 中使用 Groovy 语言访问这些变量(如构建器变量)

package dsl

// The call(body) method in any file in workflowLibs.git/vars is exposed as a
// method with the same name as the file.
def call(body) {
    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config
    body()
    try {
    
        echo "${config.builder}"

    } catch (Exception rethrow) {
        throw rethrow
    }

}

但正如我所说,我需要在 Java 中获取这些变量。 下面是我从 GlobalVariable 类继承的类。

public abstract class PipelineDSLGlobal extends GlobalVariable {

public abstract String getFunctionName();

@Override
public String getName() {
    return getFunctionName();
}

@Override
public Object getValue(CpsScript script) throws Exception {
    Binding binding = script.getBinding();

    CpsThread c = CpsThread.current();
    if (c == null)
        throw new IllegalStateException("Expected to be called from CpsThread");

    ClassLoader cl = getClass().getClassLoader();

    String scriptPath = "dsl/" + getFunctionName() + ".groovy";
    Reader r = new InputStreamReader(cl.getResourceAsStream(scriptPath), "UTF-8");

    GroovyCodeSource gsc = new GroovyCodeSource(r, getFunctionName() + ".groovy", cl.getResource(scriptPath).getFile());
    gsc.setCachable(true);
    System.out.println(gsc.toString());

    Object pipelineDSL = c.getExecution()
            .getShell()
            .getClassLoader()
            .parseClass(gsc)
            .getDeclaredConstructor()
            .newInstance();
    binding.setVariable(getName(), pipelineDSL);
    r.close();

    System.out.println("test");
    
    return pipelineDSL;
}

}

下面是我为 buildpacksdsl 创建的类。

package io.jenkins.plugins.buildpacks;

import hudson.Extension;
import io.jenkins.plugins.pipelinedsl.PipelineDSLGlobal;
import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.ProxyWhitelist;
import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist;

import java.io.IOException;

@Extension
public class BuildpacksDSL extends PipelineDSLGlobal {

@Override
public String getFunctionName() {
    return "buildpacks";
}

@Extension
public static class MiscWhitelist extends ProxyWhitelist {
    public MiscWhitelist() throws IOException {
        super(new StaticWhitelist(
                "method java.util.Map$Entry getKey",
                "method java.util.Map$Entry getValue"
        ));
    }
}

}

如果您想更详细地查看结构,可以查看repository

有人可以帮助我吗?谢谢。

【问题讨论】:

    标签: java jenkins jenkins-pipeline jenkins-plugins build-pipeline-plugin


    【解决方案1】:

    我们找到了一个小解决方案。

    我们使用 Groovy 和 Java 之间的兼容性创建了一个类的实例。 而且由于我们已经可以用Groovy获取值,所以我们可以直接在构造函数方法中传递参数。

    可能有更有效的方法。但现在它正在工作。

    // Buildpacks.groovy
    ...
    
    
    import io.jenkins.plugins.buildpacks.pipeline.BuildpacksDSL.BuildpacksPipelineDSL
    
    class Buildpacks implements Serializable {
    
        // first executed method is similar to main method in java
        public void call(final Closure body) {
    
            // the config array is the array that holds the variables.
            def config = [:]
            body.resolveStrategy = Closure.DELEGATE_FIRST
            body.delegate = config
            body()
    
            // creating a new instance, when we give the 'config' array in the constructor, the variables is transferred.
            BuildpacksPipelineDSL pipeline = new BuildpacksPipelineDSL(config)
            pipeline.build()
    
        }
    
    }
    
    ...
    
    // BuildpacksDSL.java
    
    ...
    
    
     public static class BuildpacksPipelineDSL {
    
            public BuildpacksPipelineDSL() {
            }
    
            /**
             * This constructor takes dsl parameters, logger and envs from Jenkins and
             * extracts them to local variables.
             * 
             * @param c
             * @throws Exception
             */
            public BuildpacksPipelineDSL(LinkedHashMap<String, Object> c)
                    throws Exception {
                
            // codes...
    
            }
    }
    
    ...
    

    【讨论】:

      猜你喜欢
      • 2018-06-20
      • 1970-01-01
      • 1970-01-01
      • 2017-03-05
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      相关资源
      最近更新 更多