Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
… into JENKINS-13979
  • Loading branch information
imod committed Jun 24, 2012
2 parents 1075303 + 301d7f6 commit ed0954b
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 22 deletions.
Expand Up @@ -13,8 +13,10 @@
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;

import java.io.PrintWriter;
import java.io.Serializable;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
Expand Down Expand Up @@ -79,14 +81,16 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListen
if (script != null) {
try {
// expand the parameters before passing these to the execution, this is to allow any token macro to resolve parameter values
Parameter[] expandedParams = new Parameter[parameters.length];
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
expandedParams[i] = new Parameter(parameter.getName(), TokenMacro.expandAll(build, listener, parameter.getValue()));
List<Parameter> expandedParams = new LinkedList<Parameter>();
for (Parameter parameter : parameters) {
expandedParams.add(new Parameter(parameter.getName(), TokenMacro.expandAll(build, listener, parameter.getValue())));
}
final Object output = launcher.getChannel().call(new GroovyScript(script.script, expandedParams.toArray(new Parameter[expandedParams.size()]), true, listener.getLogger()));
if (output instanceof Boolean && Boolean.FALSE.equals(output)) {
isOk = false;
} else {
isOk = true;
}
final String output = launcher.getChannel().call(new GroovyScript(script.script, expandedParams, true));
listener.getLogger().print(output);
isOk = true;
} catch (Exception e) {
listener.getLogger().print(Messages.scriptExecutionFailed(scriptId) + " - " + e.getMessage());
}
Expand Down
@@ -1,10 +1,12 @@
package org.jenkinsci.plugins.scriptler.util;

import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import hudson.remoting.DelegatingCallable;

import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;

import jenkins.model.Jenkins;

Expand All @@ -14,36 +16,36 @@
/**
* Inspired by hudson.util.RemotingDiagnostics.Script, but adding parameters.
*/
public final class GroovyScript implements DelegatingCallable<String, RuntimeException> {
public class GroovyScript implements DelegatingCallable<Object, RuntimeException> {
private static final long serialVersionUID = 1L;
private final String script;
private final Parameter[] parameters;
private final boolean failWithException;
private final PrintStream ps;
private transient ClassLoader cl;

private static final String PW_PARAM_VARIABLE = "out";

public GroovyScript(String script, Parameter[] parameters, boolean failWithException) {
public GroovyScript(String script, Parameter[] parameters, boolean failWithException, PrintStream ps) {
this.script = script;
this.parameters = parameters;
this.failWithException = failWithException;
this.ps = ps;
cl = getClassLoader();
}

public ClassLoader getClassLoader() {
return Jenkins.getInstance().getPluginManager().uberClassLoader;
}

public String call() throws RuntimeException {
public Object call() throws RuntimeException {
// if we run locally, cl!=null. Otherwise the delegating classloader will be available as context classloader.
if (cl == null) {
cl = Thread.currentThread().getContextClassLoader();
}
PrintWriter pw = new PrintWriter(ps);
GroovyShell shell = new GroovyShell(cl);

StringWriter out = new StringWriter();
PrintWriter pw = new PrintWriter(out);

for (Parameter param : parameters) {
final String paramName = param.getName();
if (PW_PARAM_VARIABLE.equals(paramName)) {
Expand All @@ -52,19 +54,22 @@ public String call() throws RuntimeException {
shell.setVariable(paramName, param.getValue());
}
}
shell.setVariable(PW_PARAM_VARIABLE, pw);
shell.setVariable(PW_PARAM_VARIABLE, ps);
try {
Object output = shell.evaluate(script);
if (output != null) {
pw.println(Messages.resultPrefix() + " " + output);
return output;
} else {
return "";
}
} catch (Throwable t) {
if (failWithException) {
throw new ScriptlerExecutionException(t);
}
t.printStackTrace(pw);
return Boolean.FALSE;
}
return out.toString();
}

private static final class ScriptlerExecutionException extends RuntimeException {
Expand Down
Expand Up @@ -2,11 +2,12 @@

import hudson.model.Computer;
import hudson.model.Hudson;
import hudson.util.RemotingDiagnostics;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Reader;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -84,15 +85,16 @@ public static String runScript(String[] slaves, String scriptTxt, Parameter[] pa
*/
public static String runScript(String node, String scriptTxt, Parameter[] parameters) throws IOException, ServletException {

String output = "[no output]";
Object output = "[no output]";
ByteArrayOutputStream sos = new ByteArrayOutputStream();
if (node != null && scriptTxt != null) {

try {

PrintStream ps = new PrintStream(sos);
Computer comp = Hudson.getInstance().getComputer(node);
if (comp == null && "(master)".equals(node)) {
// output = RemotingDiagnostics.executeGroovy(scriptTxt, MasterComputer.localChannel);
output = MasterComputer.localChannel.call(new GroovyScript(scriptTxt, parameters, false));
output = MasterComputer.localChannel.call(new GroovyScript(scriptTxt, parameters, false, ps));
} else if (comp == null) {
output = Messages.node_not_found(node) + "\n";
} else {
Expand All @@ -101,15 +103,15 @@ public static String runScript(String node, String scriptTxt, Parameter[] parame
}

else {
output = comp.getChannel().call(new GroovyScript(scriptTxt, parameters, false));
output = comp.getChannel().call(new GroovyScript(scriptTxt, parameters, false, ps));
}
}

} catch (InterruptedException e) {
throw new ServletException(e);
}
}
return output;
return sos.toString();
}

}
@@ -0,0 +1,57 @@
package org.jenkinsci.plugins.scriptler.util;

import static org.junit.Assert.assertEquals;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.jenkinsci.plugins.scriptler.config.Parameter;
import org.junit.Test;

public class GroovyScriptTest {

@Test
public void scriptReturnFalse() {
ByteArrayOutputStream sos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(sos);
GroovyScript gs = new GroovyScript("return false", new Parameter[0], true, ps) {
@Override
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
};
Object result = gs.call();
assertEquals("", sos.toString());
assertEquals(false, result);
}

@Test
public void scriptReturnTrue() {
ByteArrayOutputStream sos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(sos);
GroovyScript gs = new GroovyScript("return true", new Parameter[0], true, ps) {
@Override
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
};
Object result = gs.call();
assertEquals("", sos.toString());
assertEquals(true, result);
}

@Test
public void helloWorld() {
ByteArrayOutputStream sos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(sos);
GroovyScript gs = new GroovyScript("out.print(\"HelloWorld\")", new Parameter[0], true, ps) {
@Override
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
};
Object result = gs.call();
assertEquals("HelloWorld", sos.toString());
assertEquals("", result);
}
}

0 comments on commit ed0954b

Please sign in to comment.