Skip to content

Commit

Permalink
[FIXED JENKINS-35698] Make params offer default parameter values from…
Browse files Browse the repository at this point in the history
… the current definition as a fallback.
  • Loading branch information
jglick committed Oct 10, 2016
1 parent f752ab1 commit 0161aec
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 24 deletions.
Expand Up @@ -25,8 +25,10 @@
package org.jenkinsci.plugins.workflow.cps;

import hudson.Extension;
import hudson.model.ParameterDefinition;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.model.ParametersDefinitionProperty;
import hudson.model.Run;
import java.io.Serializable;
import java.util.Collections;
Expand All @@ -50,37 +52,51 @@
if (b == null) {
throw new IllegalStateException("cannot find owning build");
}
ParametersAction action = b.getAction(ParametersAction.class);
if (action == null) {
return Collections.emptyMap();
}
List<ParameterValue> parameterValues;
try { // TODO 1.651.2+ remove reflection
parameterValues = (List<ParameterValue>) ParametersAction.class.getMethod("getAllParameters").invoke(action);
} catch (NoSuchMethodException x) {
parameterValues = action.getParameters();
}
// Could extend AbstractMap and make a Serializable lazy wrapper, but getValue impls seem cheap anyway.
Map<String,Object> values = new HashMap<>();
for (ParameterValue parameterValue : parameterValues) {
Object value = parameterValue.getValue();
if (!(value instanceof Serializable)) {
boolean canPickle = false;
for (PickleFactory pf : PickleFactory.all()) {
if (pf.writeReplace(value) != null) {
// For example SecretPickle can handle Secret from PasswordParameterValue.
canPickle = true;
break;
ParametersAction action = b.getAction(ParametersAction.class);
if (action != null) {
List<ParameterValue> parameterValues;
try { // TODO 1.651.2+ remove reflection
parameterValues = (List<ParameterValue>) ParametersAction.class.getMethod("getAllParameters").invoke(action);
} catch (NoSuchMethodException x) {
parameterValues = action.getParameters();
}
for (ParameterValue parameterValue : parameterValues) {
addValue(values, parameterValue);
}
}
ParametersDefinitionProperty prop = b.getParent().getProperty(ParametersDefinitionProperty.class);
if (prop != null) { // JENKINS-35698: look for default values as well
for (ParameterDefinition param : prop.getParameterDefinitions()) {
if (!values.containsKey(param.getName())) {
ParameterValue defaultParameterValue = param.getDefaultParameterValue();
if (defaultParameterValue != null) {
addValue(values, defaultParameterValue);
}
}
if (!canPickle) {
// Just skip anything not serializable, such as a Run from a RunParameterValue.
continue;
}
}
values.put(parameterValue.getName(), value);
}
return Collections.unmodifiableMap(values);
}

private static void addValue(Map<String, Object> values, ParameterValue parameterValue) {
Object value = parameterValue.getValue();
if (!(value instanceof Serializable)) {
boolean canPickle = false;
for (PickleFactory pf : PickleFactory.all()) {
if (pf.writeReplace(value) != null) {
// For example SecretPickle can handle Secret from PasswordParameterValue.
canPickle = true;
break;
}
}
if (!canPickle) {
// Just skip anything not serializable, such as a Run from a RunParameterValue.
return;
}
}
values.put(parameterValue.getName(), value);
}

}
Expand Up @@ -29,4 +29,17 @@ THE SOFTWARE.
Exposes all parameters defined in the build as a read-only map with variously typed values. Example:
</p>
<pre><code>if (params.BOOLEAN_PARAM_NAME) {doSomething()}</code></pre>
<p>
Note for multibranch (<code>Jenkinsfile</code>) usage: the <code>properties</code> step allows you to define job properties,
but these take effect when the step is run, whereas build parameter definitions are generally consulted before the build begins.
As a convenience, any parameters <em>currently</em> defined in the job which have default values will also be listed in this map.
That allows you to write, for example:
</p>
<pre><code>properties([parameters([string(name: 'BRANCH', defaultValue: 'master')])])
git url: '…', branch: params.BRANCH
</code></pre>
<p>
and be assured that the <code>master</code> branch will be checked out even in the initial build of a branch project,
or if the previous build did not specify parameters or used a different parameter name.
</p>
</j:jelly>

0 comments on commit 0161aec

Please sign in to comment.