Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ protected String getDefaultMessageCause() {

@Override
protected Action[] getScheduledActions(Node pollingNode, final XTriggerLog log) throws ScriptTriggerException {
Action[] fileParametersActions = new Action[0];
Action[] cronTabParametersActions = new Action[0];

if (propertiesFilePath != null) {
try {
Expand All @@ -127,7 +129,7 @@ protected Action[] getScheduledActions(Node pollingNode, final XTriggerLog log)
if (rootPath == null) {
throw new ScriptTriggerException("The node is offline.");
}
return rootPath.act(new FilePath.FileCallable<Action[]>() {
fileParametersActions = rootPath.act(new FilePath.FileCallable<Action[]>() {

public Action[] invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
File propFile = new File(propertiesFilePath);
Expand All @@ -141,23 +143,7 @@ public Action[] invoke(File f, VirtualChannel channel) throws IOException, Inter
properties.load(fis);
fis.close();

assert job != null : "job must not be null if this was 'started'";
ParametersDefinitionProperty paramDefProp = (ParametersDefinitionProperty) ((Job) job)
.getProperty(ParametersDefinitionProperty.class);
List<ParameterValue> parameterValueList = new ArrayList<ParameterValue>();

/* Scan for all parameter with an associated default values */
for (ParameterDefinition paramDefinition : paramDefProp.getParameterDefinitions()) {
ParameterValue defaultValue = paramDefinition.getDefaultParameterValue();

if (properties.containsKey(paramDefinition.getName())) {
ParameterizedStaplerRequest request = new ParameterizedStaplerRequest(
String.valueOf(properties.get(paramDefinition.getName())));
parameterValueList.add(paramDefinition.createValue(request));
} else if (defaultValue != null)
parameterValueList.add(defaultValue);
}
return new Action[]{new ParametersAction(parameterValueList)};
return getParametersActions(properties);
}
});
} catch (IOException ioe) {
Expand All @@ -166,6 +152,30 @@ public Action[] invoke(File f, VirtualChannel channel) throws IOException, Inter
throw new ScriptTriggerException(ie);
}
}

Properties cronTabParameters = new Properties();
try {
cronTabParameters.putAll(
new ParameterParser().findParameters(getSpec(), new GregorianCalendar()));
} catch (ANTLRException e) {
throw new ScriptTriggerException(e);
}

if (! cronTabParameters.isEmpty()) {
cronTabParametersActions = getParametersActions(cronTabParameters);
}

if (fileParametersActions.length > 0 && cronTabParametersActions.length > 0) {
ParametersAction fileParametersAction = (ParametersAction) fileParametersActions[0];
ParametersAction cronTabParametersAction = (ParametersAction) cronTabParametersActions[0];
// Cron Tab parameters overrides File parameters.
return new Action[]{fileParametersAction.merge(cronTabParametersAction)};
} else if (fileParametersActions.length > 0) {
return fileParametersActions;
} else if (cronTabParametersActions.length > 0) {
return cronTabParametersActions;
}

return new Action[0];
}

Expand All @@ -175,6 +185,10 @@ protected boolean checkIfModified(Node pollingNode, XTriggerLog log) throws Scri
SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
try {

Properties parameters =
new ParameterParser().findParameters(getSpec(), new GregorianCalendar());
log.info("[debug] Parameters: " + parameters);

GroovyScriptTriggerExecutor executor = getGroovyScriptTriggerExecutor(log);
final AbstractProject proj = (AbstractProject) job;

Expand All @@ -187,25 +201,46 @@ protected boolean checkIfModified(Node pollingNode, XTriggerLog log) throws Scri
}

if (groovyExpression != null) {
boolean evaluationSucceed = executor.evaluateGroovyScript(pollingNode, proj, getGroovyExpression(), envVars, groovySystemScript);
boolean evaluationSucceed = executor.evaluateGroovyScript(pollingNode, proj, getGroovyExpression(), envVars, parameters, groovySystemScript);
if (evaluationSucceed) {
return true;
}
}

if (groovyFilePath != null) {
boolean evaluationSucceed = executor.evaluateGroovyScriptFilePath(pollingNode, proj, Util.replaceMacro(groovyFilePath, envVars), envVars, groovySystemScript);
boolean evaluationSucceed = executor.evaluateGroovyScriptFilePath(pollingNode, proj, Util.replaceMacro(groovyFilePath, envVars), envVars, parameters, groovySystemScript);
if (evaluationSucceed) {
return true;
}
}

return false;
} catch (ANTLRException e) {
throw new ScriptTriggerException(e);
} finally {
SecurityContextHolder.getContext().setAuthentication(existingAuth);
}
}

protected Action[] getParametersActions(Properties properties) {
assert job != null : "job must not be null if this was 'started'";
ParametersDefinitionProperty paramDefProp = (ParametersDefinitionProperty) ((Job) job)
.getProperty(ParametersDefinitionProperty.class);
List<ParameterValue> parameterValueList = new ArrayList<ParameterValue>();
/* Scan for all parameter with an associated default values */
for (ParameterDefinition paramDefinition : paramDefProp.getParameterDefinitions()) {
ParameterValue defaultValue = paramDefinition.getDefaultParameterValue();

if (properties.containsKey(paramDefinition.getName())) {
ParameterizedStaplerRequest request = new ParameterizedStaplerRequest(
String.valueOf(properties.get(paramDefinition.getName())));
parameterValueList.add(paramDefinition.createValue(request));
} else if (defaultValue != null)
parameterValueList.add(defaultValue);
}
return new Action[]{new ParametersAction(parameterValueList)};
}

private GroovyScriptTriggerExecutor getGroovyScriptTriggerExecutor(XTriggerLog log) throws ScriptTriggerException {
return new GroovyScriptTriggerExecutor(log);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;

/**
* @author Gregory Boissinot
Expand All @@ -48,21 +49,21 @@ public GroovyScriptTriggerExecutor(XTriggerLog log) {
super(log);
}

public boolean evaluateGroovyScript(Node executingNode, final AbstractProject proj, final String scriptContent, final Map<String, String> envVars, boolean groovySystemScript) throws ScriptTriggerException {
public boolean evaluateGroovyScript(Node executingNode, final AbstractProject proj, final String scriptContent, final Map<String, String> envVars, final Properties parameters, boolean groovySystemScript) throws ScriptTriggerException {

if (scriptContent == null) {
throw new NullPointerException("The script content object must be set.");
}
try {
if (groovySystemScript) {
log.info("Running as system script");
return evaluateGroovyScript(proj, scriptContent, envVars);
return evaluateGroovyScript(proj, scriptContent, envVars, parameters);
}

return executingNode.getRootPath().act(new Callable<Boolean, ScriptTriggerException>() {
public Boolean call() throws ScriptTriggerException {
log.info("Running as node script");
return evaluateGroovyScript(null, scriptContent, envVars);
return evaluateGroovyScript(null, scriptContent, envVars, parameters);
}
});
} catch (IOException ioe) {
Expand All @@ -80,7 +81,7 @@ public Boolean call() throws ScriptTriggerException {
}
}

private boolean evaluateGroovyScript(final AbstractProject proj, final String scriptContent, final Map<String, String> envVars) {
private boolean evaluateGroovyScript(final AbstractProject proj, final String scriptContent, final Map<String, String> envVars, final Properties parameters) {
if (envVars != null) {
final StringBuilder envDebug = new StringBuilder("Replacing script vars using:");
for (final Map.Entry<String, String> envEntry : envVars.entrySet()) {
Expand Down Expand Up @@ -108,6 +109,7 @@ private boolean evaluateGroovyScript(final AbstractProject proj, final String sc

shell.setVariable("log", log);
shell.setVariable("out", log.getListener().getLogger());
shell.setVariable("parameters", parameters);
if (proj != null) {
shell.setVariable("project", proj);
}
Expand Down Expand Up @@ -148,7 +150,7 @@ protected ClassLoader getClassLoader() {
return cl;
}

public boolean evaluateGroovyScriptFilePath(Node executingNode, AbstractProject proj, String scriptFilePath, Map<String, String> envVars, boolean groovySystemScript) throws ScriptTriggerException {
public boolean evaluateGroovyScriptFilePath(Node executingNode, AbstractProject proj, String scriptFilePath, Map<String, String> envVars, final Properties parameters, boolean groovySystemScript) throws ScriptTriggerException {

if (scriptFilePath == null) {
throw new NullPointerException("The scriptFilePath object must be set.");
Expand Down Expand Up @@ -189,7 +191,7 @@ public boolean evaluateGroovyScriptFilePath(Node executingNode, AbstractProject
scriptContent = getStringContent(executingNode, scriptFilePath);
}

return evaluateGroovyScript(executingNode, proj, scriptContent, envVars, groovySystemScript);
return evaluateGroovyScript(executingNode, proj, scriptContent, envVars, parameters, groovySystemScript);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.jenkinsci.plugins.scripttrigger.groovy;

import antlr.ANTLRException;
import hudson.scheduler.CronTabList;
import org.apache.commons.lang.StringUtils;

import java.util.Calendar;
import java.util.Properties;

public class ParameterParser {

private static final String PARAMETER_ANNOTATION = "@param";

public Properties findParameters(String cronTabSpec, Calendar calendar) throws ANTLRException {
Properties parameters = new Properties();
for (String line : cronTabSpec.split(System.lineSeparator())) {
if (line.length() == 0) {
continue;
}
if (line.startsWith("#")) {
if (line.substring(1).startsWith(PARAMETER_ANNOTATION)) {
parameters.putAll(parseParameters(line.substring(1 + PARAMETER_ANNOTATION.length())));
}
} else {
if (CronTabList.create(line).check(calendar)) {
break;
}
parameters.clear();
}
}
return parameters;
}

private Properties parseParameters(String parameterStr) {
Properties parameters = new Properties();
if (StringUtils.isBlank(parameterStr)) {
return parameters;
}
parameterStr = parameterStr.trim();
int separatorInd = parameterStr.indexOf(' ');
if (separatorInd < 0) {
parameters.setProperty(parameterStr, "");
} else {
parameters.setProperty(parameterStr.substring(0, separatorInd), parameterStr.substring(separatorInd).trim());
}
return parameters;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,19 @@
f.exists()
</i>
</p>
<p>
Scheduler field supports parameters in format:<br/>
<code>#@param &lt;name&gt; [value]</code><br/>
<br/>
Parameters are applied to a cron item above which they are listed.<br/>
These parameters values override ones of default job parameters.<br/>
No quotes are needed in case a parameter value contains whitespaces.<br/>
A parameter value may be omitted. In this case it will be assumed as an empty one.
</p>
<p>
Predefined variables:
</p>
<dl>
<dt><code>parameters</code></dt><dd>Parameters defined in Scheduler.</dd>
</dl>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,19 @@
<p>
Give a groovy script path.
</p>
<p>
Scheduler field supports parameters in format:<br/>
<code>#@param &lt;name&gt; [value]</code><br/>
<br/>
Parameters are applied to a cron item above which they are listed.<br/>
These parameters values override ones of default job parameters.<br/>
No quotes are needed in case a parameter value contains whitespaces.<br/>
A parameter value may be omitted. In this case it will be assumed as an empty one.
</p>
<p>
Predefined variables:
</p>
<dl>
<dt><code>parameters</code></dt><dd>Parameters defined in Scheduler.</dd>
</dl>
</div>