package hudson.plugins.gant; import hudson.tasks.Builder; import hudson.model.BuildListener; import hudson.model.Descriptor; import hudson.Extension; import hudson.Launcher; import hudson.Util; import hudson.CopyOnWrite; import hudson.model.AbstractBuild; import hudson.model.Hudson; import hudson.util.ArgumentListBuilder; import hudson.util.FormValidation; import java.io.IOException; import java.io.File; import java.util.Map; import net.sf.json.JSONObject; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; /** * @author Kohsuke Kawaguchi */ public class Gant extends Builder { /** * The targets, properties, and other Gant options. * Either separated by whitespace or newline. */ private final String targets; /** * Identifies {@link GantInstallation} to be used. */ private final String gantName; @DataBoundConstructor public Gant(String targets,String gantName) { this.targets = targets; this.gantName = gantName; } public String getTargets() { return targets; } /** * Gets the Gant to invoke, * or null to invoke the default one. */ public GantInstallation getGant() { for( GantInstallation i : DESCRIPTOR.getInstallations() ) { if(gantName!=null && i.getName().equals(gantName)) return i; } return null; } @Override public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { ArgumentListBuilder args = new ArgumentListBuilder(); String execName; if(launcher.isUnix()) execName = "gant"; else execName = "gant.bat"; String normalizedTarget = targets.replaceAll("[\t\r\n]+"," "); GantInstallation ai = getGant(); if(ai==null) { args.add(execName); } else { File exec = ai.getExecutable(); if(!ai.getExists()) { listener.fatalError(exec+" doesn't exist"); return false; } args.add(exec.getPath()); } args.addKeyValuePairs("-D",build.getBuildVariables()); args.addTokenized(normalizedTarget); Map<String,String> env = build.getEnvironment(listener); if(ai!=null) env.put("GROOVY_HOME",ai.getGroovyHome()); if(!launcher.isUnix()) { // on Windows, executing batch file can't return the correct error code, // so we need to wrap it into cmd.exe. // double %% is needed because we want ERRORLEVEL to be expanded after // batch file executed, not before. This alone shows how broken Windows is... args.prepend("cmd.exe","/C"); args.add("&&","exit","%%ERRORLEVEL%%"); } try { int r = launcher.launch().cmds(args).envs(env).stdout(listener.getLogger()).pwd(build.getModuleRoot()).join(); return r==0; } catch (IOException e) { Util.displayIOException(e,listener); e.printStackTrace( listener.fatalError("command execution failed") ); return false; } } @Override public Descriptor<Builder> getDescriptor() { return DESCRIPTOR; } @Extension public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); public static final class DescriptorImpl extends Descriptor<Builder> { @CopyOnWrite private volatile GantInstallation[] installations = new GantInstallation[0]; private DescriptorImpl() { super(Gant.class); load(); } @Override public String getHelpFile() { return "/plugin/gant/help.html"; } public String getDisplayName() { return "Invoke Gant script"; } public GantInstallation[] getInstallations() { return installations; } @Override public boolean configure(StaplerRequest req, JSONObject formData) { installations = req.bindParametersToList( GantInstallation.class,"gant.").toArray(new GantInstallation[0]); save(); return true; } // // web methods // /** * Checks if the GROOVY_HOME is valid. */ public FormValidation doCheckGroovyHome(@QueryParameter final String value) { // this can be used to check the existence of a file on the server, so needs to be protected if (!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) return FormValidation.ok(); File f = new File(Util.fixNull(value)); if(!f.isDirectory()) { return FormValidation.error(f+" is not a directory"); } if(!new File(f,"bin/groovy").exists() && !new File(f,"bin/groovy.bat").exists()) { return FormValidation.error(f+" doesn't look like a Groovy directory"); } if(!new File(f,"bin/gant").exists() && !new File(f,"bin/gant.bat").exists()) { return FormValidation.error(f+" looks like a Groovy but Gant is not found in here"); } return FormValidation.ok(); } } }