Package hudson.plugins.groovy

Source Code of hudson.plugins.groovy.Groovy$GroovyInstallation

package hudson.plugins.groovy;

import hudson.CopyOnWrite;
import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.model.BuildListener;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Computer;
import hudson.model.ParametersAction;
import hudson.util.VariableResolver;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.StringTokenizer;

import jenkins.model.Jenkins;
import net.sf.json.JSONObject;

import org.apache.commons.exec.CommandLine;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

/**
* A Builder for Groovy scripts.
*
* @author dvrzalik, vjuranek
*/
public class Groovy extends AbstractGroovy {
   
    private String groovyName;
    private String parameters;
    private String scriptParameters;
    private String properties; // -D properties
    private String javaOpts;   //sometimes other options than -D are needed to be set up, like -XX. It can be done here.
                   // Properties are kept for user, who don't want bother with -D and backward compatibility

    private String classPath;  //for user convenience when added more item into class path not have to deal with path separator
   
    @DataBoundConstructor
    public Groovy(ScriptSource scriptSource, String groovyName, String parameters,
            String scriptParameters, String properties, String javaOpts, String classPath) {
        super(scriptSource);
        this.groovyName = groovyName;
        this.parameters = parameters;
        this.scriptParameters = scriptParameters;
        this.properties = properties;
        this.javaOpts = javaOpts;
        this.classPath = classPath;
    }


    @Override
    public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {

        if (scriptSource == null) {
            listener.fatalError("There is no script configured for this builder");
            return false;
        }

        FilePath ws = build.getWorkspace();
        FilePath script = null;
        try {
            script = scriptSource.getScriptFile(ws,build,listener);
        } catch (IOException e) {
            Util.displayIOException(e, listener);
            e.printStackTrace(listener.fatalError("Unable to produce a script file"));
            return false;
        }
        try {
            List<String> cmd = buildCommandLine(build,listener,script,launcher.isUnix());

            int result;
            try {
                Map<String,String> envVars = build.getEnvironment(listener);
                hudson.plugins.groovy.GroovyInstallation installation = getGroovy();
                if(installation != null) {
                    installation = installation.forNode(Computer.currentComputer().getNode(), listener);
                    envVars.put("GROOVY_HOME", installation.getHome());
                }

                for(Map.Entry<String,String> e : build.getBuildVariables().entrySet()){
                    envVars.put(e.getKey(),e.getValue());
                }

                if(properties != null) {
                    String origJavaOpts = build.getBuildVariables().get("JAVA_OPTS");
                    StringBuffer javaOpts = new StringBuffer((origJavaOpts != null) ? origJavaOpts : "");
                    Properties props = parseProperties(properties);
                   
                    for (Entry<Object,Object> entry : props.entrySet()) {
                        cmd.add(1, "-D" + entry.getKey() + "=" + entry.getValue());
                    }

                    //Add javaOpts at the end
                    if(this.javaOpts != null) //backward compatibility
                      javaOpts.append(" " + this.javaOpts);
                   
                    envVars.put("JAVA_OPTS", javaOpts.toString());
                }
                envVars.put("$PATH_SEPARATOR",":::");
               
                result = launcher.launch().cmds(cmd.toArray(new String[] {})).envs(envVars).stdout(listener).pwd(ws).join();
            } catch (IOException e) {
                Util.displayIOException(e,listener);
                e.printStackTrace( listener.fatalError("command execution failed") );
                result = -1;
            }
            return result==0;
        } finally {
            try {
                if((scriptSource instanceof StringScriptSource) && (script!=null)){
                  script.delete();
                }
            } catch (IOException e) {
                Util.displayIOException(e,listener);
                e.printStackTrace( listener.fatalError("Unable to delete script file "+script) );
            }
        }
    }

    @Extension
    public static final class DescriptorImpl extends AbstractGroovyDescriptor {

      private boolean allowMacro;
     
      @CopyOnWrite
        private volatile GroovyInstallation[] installations = new GroovyInstallation[0];
     
        @CopyOnWrite
        private volatile List<hudson.plugins.groovy.GroovyInstallation> installations2 = new ArrayList<hudson.plugins.groovy.GroovyInstallation>();

        public DescriptorImpl() {
            super(Groovy.class);
            load();
        }
       
        public Object readResolve(){
          // convert to new installation and drop the old one
          if(installations.length > 0){
            for(GroovyInstallation inst: installations){
              hudson.plugins.groovy.GroovyInstallation inst2 = new hudson.plugins.groovy.GroovyInstallation(inst.getName(),inst.getHome(),null);
              installations2.add(inst2);
            }
            installations = null;
          }
          return this;
        }
       
        public boolean getAllowMacro(){
          return allowMacro;
        }

        public String getDisplayName() {
            return "Execute Groovy script";
        }

        @Override
        public boolean isApplicable(Class<? extends AbstractProject> jobType){
          return true;
        }
       
        @Override
        public String getHelpFile() {
            return "/plugin/groovy/project-config.html";
        }

        public hudson.plugins.groovy.GroovyInstallation[] getInstallations() {
          hudson.plugins.groovy.GroovyInstallation[] installs = new hudson.plugins.groovy.GroovyInstallation[installations2.size()];
            return installations2.toArray(installs);
        }
   
        public static hudson.plugins.groovy.GroovyInstallation getGroovy(String groovyName) {
            for( hudson.plugins.groovy.GroovyInstallation i : ((DescriptorImpl) Jenkins.getInstance().getDescriptor(Groovy.class)).getInstallations()) {
                if(groovyName!=null && i.getName().equals(groovyName))
              return i;
            }
          return null;
        }
       
        public void setInstallations(hudson.plugins.groovy.GroovyInstallation... installations) { 
            //this.installations = installations;
          this.installations2 = new ArrayList<hudson.plugins.groovy.GroovyInstallation>();
          for(hudson.plugins.groovy.GroovyInstallation install: installations){
            this.installations2.add(install);
          }
            save();                                                                                                                           
        }    

        @Override
        public boolean configure(StaplerRequest req, JSONObject json) throws hudson.model.Descriptor.FormException {
            allowMacro = json.getBoolean("allowMacro");
            save();
            return true;
        }
    }

   
    // Keep it for backward compatibility
    public static final class GroovyInstallation implements Serializable {

        private final String name;
        private final String home;

        @DataBoundConstructor
        public GroovyInstallation(String name, String home) {
            this.name = name;
            this.home = home;
        }

        /**
         * install directory.
         */
        public String getHome() {
            return home;
        }

        /**
         * Human readable display name.
         */
        public String getName() {
            return name;
        }

     
        private static final long serialVersionUID = 1L;
    }


    protected hudson.plugins.groovy.GroovyInstallation getGroovy() {
        return DescriptorImpl.getGroovy(groovyName);
    }

    //backward compatibility, default is Unix
    protected List<String> buildCommandLine(AbstractBuild build,FilePath script) throws IOException, InterruptedException  {
      return buildCommandLine(build, null, script, true);
    }
   
    protected List<String> buildCommandLine(AbstractBuild build, BuildListener listener, FilePath script, boolean isOnUnix) throws IOException, InterruptedException  {
        ArrayList<String> list = new ArrayList<String>();

        //prepare variable resolver - more efficient than calling env.expand(s)
        EnvVars env = build.getEnvironment(listener);
        env.overrideAll(build.getBuildVariables());
        VariableResolver<String> vr = new VariableResolver.ByMap<String>(env);
       
       
        String cmd = "groovy";//last hope in case of missing or not selected installation

        hudson.plugins.groovy.GroovyInstallation installation = getGroovy();
        if(installation != null) {
          installation = installation.forNode(Computer.currentComputer().getNode(), listener);                                                                     
          installation = installation.forEnvironment(env);  
            cmd = installation.getExecutable(script.getChannel());
            //some misconfiguration, reverting back to default groovy cmd
            if(null == cmd){
              cmd = "groovy";
              listener.getLogger().println("[GROOVY WARNING] Groovy executable is NULL, please check your Groovy configuration, trying fallback 'groovy' instead.");
            }
        }
        list.add(cmd);

        //Add class path
        if(classPath != null && !classPath.equals("")){
          String pathSeparator = isOnUnix ? ":" : ";";
          StringTokenizer tokens = new StringTokenizer(classPath);
          list.add("-cp");
          // class path has to be one item, otherwise spaces are add around class path separator and build will fail
          StringBuilder sb = new StringBuilder()
          sb.append(Util.replaceMacro(tokens.nextToken(),vr));
            while(tokens.hasMoreTokens()) {
              sb.append(pathSeparator);
                sb.append(Util.replaceMacro(tokens.nextToken(),vr));
            }
            list.add(sb.toString());
        }
       
        //Add groovy parameters
        if(parameters != null && !parameters.isEmpty()) {
            String[] args = parseParams(parameters);
            for(String arg : args) {
                list.add(Util.replaceMacro(arg, vr));
            }
        }

        list.add(script.getRemote());

        //Add script parameters
        if(scriptParameters != null && !scriptParameters.isEmpty()) {
            String[] params = parseParams(scriptParameters);
            ParametersAction parameters = build.getAction(ParametersAction.class);
            for(String param : params) {
              //first replace parameter from parameterized build
              if (parameters != null) {
                    param = parameters.substitute(build, param);
                }
              //then replace evn vars
              param = Util.replaceMacro(param,vr);
                list.add(param);
            }
        }

        return list;

    }
   
    /**
     * Parse parameters to be passed as arguments to the groovy binary
     *
     */
    private String[] parseParams(String line) {
        //JENKINS-24870 CommandLine.getExecutable tries to fix file separators, so if the first param contains slashes, it can cause problems
        //Adding some placeholder instead of executable
        CommandLine cmdLine = CommandLine.parse("executable_placeholder " + line)
        String[] parsedArgs = cmdLine.getArguments();
        String[] args = new String[parsedArgs.length];
        if(parsedArgs.length > 0) {
            System.arraycopy(parsedArgs, 0, args, 0, parsedArgs.length);
        }
        return args;
    }


    public String getCommand() {
        return command;
    }

    public String getScriptFile() {
        return scriptFile;
    }

    public String getGroovyName() {
        return groovyName;
    }

    public BuilderType getType() {
        return type;
    }

    public String getParameters() {
        return parameters;
    }

    public String getScriptParameters() {
        return scriptParameters;
    }

    public String getProperties() {
        return properties;
    }
   
    public String getJavaOpts(){
      return javaOpts;
    }
   
    public String getClassPath(){
      return classPath;
    }
   
    //---- Backward compatibility -------- //
   
    public enum BuilderType { COMMAND,FILE }
   
    private BuilderType type;
    private String command;
    private String scriptFile;
   
    private Object readResolve() {
        if (type != null) {
            switch (type) {
                case COMMAND:
                    scriptSource = new StringScriptSource(command);
                    break;
                case FILE:
                    scriptSource = new FileScriptSource(scriptFile);
                    break;
            }
        }
       
        type = null;
        command = null;
        scriptFile = null;
       
        return this;
    }

}
TOP

Related Classes of hudson.plugins.groovy.Groovy$GroovyInstallation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.