Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

Commit

Permalink
[JENKINS-26093] Allow parameter values to be specified using standard…
Browse files Browse the repository at this point in the history
… $class syntax.
  • Loading branch information
jglick committed Mar 3, 2015
1 parent 35aa4cf commit 72860e9
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -5,6 +5,7 @@ Only noting significant user-visible or major API changes, not internal code cle
## 1.3 (upcoming)

### User changes
* JENKINS-26093: `build` can now accept `parameters` in a more uniform (and sandbox-friendly) syntax.
* JENKINS-25890: deadlock during restart.
* Fixed some file handle leaks caught by tests which may have affected Windows masters.
* JENKINS-25779: snippet generator now omits default values of complex steps.
Expand Down
Expand Up @@ -160,12 +160,11 @@ public void cancelBuildQueue() throws Exception {
Cause.UpstreamCause cause = ds1.getCause(Cause.UpstreamCause.class);
assertNotNull(cause);
assertEquals(us1, cause.getUpstreamRun());
// TODO JENKINS-26093 let us bind a simple Groovy map
us.setDefinition(new CpsFlowDefinition("build job: 'ds', parameters: [new hudson.model.StringParameterValue('branch', 'release')]"));
us.setDefinition(new CpsFlowDefinition("build job: 'ds', parameters: [[$class: 'StringParameterValue', name: 'branch', value: 'release']]", true));
j.assertBuildStatusSuccess(us.scheduleBuild2(0));
// TODO IIRC there is an open PR regarding automatic filling in of default parameter values; should that be used, or is BuildTriggerStepExecution responsible, or ParameterizedJobMixIn.scheduleBuild2?
// TODO JENKINS-13768 proposes automatic filling in of default parameter values; should that be used, or is BuildTriggerStepExecution responsible, or ParameterizedJobMixIn.scheduleBuild2?
j.assertLogContains("branch=release extra=", ds.getBuildByNumber(2));
us.setDefinition(new CpsFlowDefinition("build job: 'ds', parameters: [new hudson.model.StringParameterValue('branch', 'release'), new hudson.model.BooleanParameterValue('extra', true)]"));
us.setDefinition(new CpsFlowDefinition("build job: 'ds', parameters: [[$class: 'StringParameterValue', name: 'branch', value: 'release'], [$class: 'BooleanParameterValue', name: 'extra', value: true]]", true));
j.assertBuildStatusSuccess(us.scheduleBuild2(0));
j.assertLogContains("branch=release extra=true", ds.getBuildByNumber(3));
}
Expand Down
Expand Up @@ -101,11 +101,7 @@ public class SnippetizerTest {
BuildTriggerStep step = new BuildTriggerStep("downstream");
assertRoundTrip(step, "build 'downstream'");
step.setParameters(Arrays.asList(new StringParameterValue("branch", "default"), new BooleanParameterValue("correct", true)));
/* TODO figure out how to add support for ParameterValue without those having Descriptor’s yet
currently instantiate works but uninstantiate does not offer a FQN
(which does not matter in this case since BuildTriggerStep/config.jelly does not offer to bind parameters anyway)
assertRoundTrip(step, "build job: 'downstream', parameters: [[$class: 'hudson.model.StringParameterValue', name: 'branch', value: 'default'], [$class: 'hudson.model.BooleanParameterValue', name: 'correct', value: true]]");
*/
assertRoundTrip(step, "build job: 'downstream', parameters: [[$class: 'StringParameterValue', name: 'branch', value: 'default'], [$class: 'BooleanParameterValue', name: 'correct', value: true]]");
}

@Issue("JENKINS-25779")
Expand Down
Expand Up @@ -28,6 +28,8 @@
import com.google.common.primitives.Primitives;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.model.ParameterDefinition;
import hudson.model.ParameterValue;
import java.beans.Introspector;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
Expand Down Expand Up @@ -390,6 +392,21 @@ static <T> Set<Class<? extends T>> findSubtypes(Class<T> supertype) {
clazzes.add(d.clazz.asSubclass(supertype));
}
}
if (supertype == ParameterValue.class) { // TODO JENKINS-26093 hack, pending core change
for (Class<? extends ParameterDefinition> d : findSubtypes(ParameterDefinition.class)) {
String name = d.getName();
if (name.endsWith("Definition")) {
try {
Class<?> c = d.getClassLoader().loadClass(name.replaceFirst("Definition$", "Value"));
if (supertype.isAssignableFrom(c)) {
clazzes.add(c.asSubclass(supertype));
}
} catch (ClassNotFoundException x) {
// ignore
}
}
}
}
return clazzes;
}

Expand Down
Expand Up @@ -27,7 +27,9 @@
import hudson.Extension;
import hudson.Main;
import hudson.model.AbstractDescribableImpl;
import hudson.model.BooleanParameterValue;
import hudson.model.Descriptor;
import hudson.model.ParameterValue;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -430,6 +432,35 @@ public static final class DefaultStructArray {
@Override public String toString() {return "DefaultStructArray" + Arrays.toString(bases) + ";stuff=" + stuff;}
}

@Issue("JENKINS-26093")
@Test public void parameterValues() throws Exception {
assertTrue(DescribableHelper.findSubtypes(ParameterValue.class).contains(BooleanParameterValue.class)); // do not want to enumerate ListSubversionTagsParameterValue etc.
// Omitting RunParameterValue since it is not friendly for a unit test.
// JobParameterDefinition is not registered as an extension, so not supporting FileParameterValue.
// FileParameterValue is unsupportable as an input to a WorkflowJob since it requires createBuildWrapper to work;
// as an argument to BuildTriggerStep it could perhaps work, but we would need to provide a custom FileItem implementation.
// PasswordParameterValue requires Secret.fromString and thus JenkinsRule.
// For others: https://github.com/search?type=Code&q=user%3Ajenkinsci+user%3Acloudbees+%22extends+ParameterDefinition%22
roundTrip(TakesParams.class, map("parameters", Arrays.asList(
map("$class", "BooleanParameterValue", "name", "flag", "value", true),
map("$class", "StringParameterValue", "name", "n", "value", "stuff"),
map("$class", "TextParameterValue", "name", "text", "value", "here\nthere"))),
"TakesParams;BooleanParameterValue:flag=true;StringParameterValue:n=stuff;TextParameterValue:text=here\nthere");
}
public static final class TakesParams {
public final List<ParameterValue> parameters;
@DataBoundConstructor public TakesParams(List<ParameterValue> parameters) {
this.parameters = parameters;
}
@Override public String toString() {
StringBuilder b = new StringBuilder("TakesParams");
for (ParameterValue v : parameters) {
b.append(';').append(v.getClass().getSimpleName()).append(':').append(v.getShortDescription());
}
return b.toString();
}
}

private static Map<String,Object> map(Object... keysAndValues) {
if (keysAndValues.length % 2 != 0) {
throw new IllegalArgumentException();
Expand Down
Expand Up @@ -29,8 +29,8 @@ THE SOFTWARE.
<f:textbox/>
</f:entry>
<f:entry title="Parameters">
<!-- TODO JENKINS-26093 -->
<f:block><code>parameters</code> may be bound to a list of <code>ParameterValue</code>s.</f:block>
<!-- TODO JENKINS-26093 load *ParameterDefinition/index.jelly blocks from downstream project -->
<f:block>To set parameters, use for example: <code>parameters: [[$class: 'StringParameterValue', name: 'branch', value: 'master']]</code></f:block>
</f:entry>
<f:entry field="wait">
<f:checkbox default="true" title="Wait for completion"/>
Expand Down

0 comments on commit 72860e9

Please sign in to comment.