Skip to content

Commit

Permalink
JENKINS-25744 Switch job property to use an optionalBlock
Browse files Browse the repository at this point in the history
Normal convention for Jenkins plugins which contribute a JobProperty to a jobs
configuration page is to use an optionalBlock as the top level jelly tag.

In a jobs properties section of the configuration page, plugins 'hide' their
configuration entries by using the optionalBlock, this is presented to the user
as a checkbox. This keeps the jobs configuration page quite clean while allowing
the user full control over the properties they use.
  • Loading branch information
fluffy88 committed Nov 22, 2014
1 parent 8310d8a commit 5cf6bd6
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 54 deletions.
56 changes: 37 additions & 19 deletions src/main/java/se/diabol/jenkins/pipeline/PipelineProperty.java
Expand Up @@ -19,9 +19,12 @@

import hudson.Extension;
import hudson.model.*;
import hudson.model.Descriptor.FormException;
import hudson.util.FormValidation;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;

import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.export.Exported;
Expand All @@ -34,13 +37,16 @@ public class PipelineProperty extends JobProperty<AbstractProject<?, ?>> {

private String taskName = null;
private String stageName = null;
private boolean configEnabled = true;

public PipelineProperty() {
}

public PipelineProperty(String taskName, String stageName) {
@DataBoundConstructor
public PipelineProperty(String taskName, String stageName, boolean configEnabled) {
setStageName(stageName);
setTaskName(taskName);
setConfigEnabled(configEnabled);
}

@Exported
Expand All @@ -52,6 +58,11 @@ public String getTaskName() {
public String getStageName() {
return stageName;
}

@Exported
public boolean getConfigEnabled() {
return configEnabled;
}

public final void setTaskName(String taskName) {
this.taskName = taskName;
Expand All @@ -61,6 +72,10 @@ public final void setStageName(String stageName) {
this.stageName = stageName;
}

public final void setConfigEnabled(boolean configEnabled) {
this.configEnabled = configEnabled;
}

public static Set<String> getStageNames() {
List<AbstractProject> projects = Jenkins.getInstance().getAllItems(AbstractProject.class);
Set<String> result = new HashSet<String>();
Expand All @@ -77,6 +92,8 @@ public static Set<String> getStageNames() {

@Extension
public static final class DescriptorImpl extends JobPropertyDescriptor {

@Override
public String getDisplayName() {
return "Pipeline description";
}
Expand Down Expand Up @@ -118,25 +135,26 @@ protected FormValidation checkValue(String value) {
return FormValidation.error("Value needs to be empty or include characters and/or numbers");
}
return FormValidation.ok();

}


@Override
public PipelineProperty newInstance(StaplerRequest sr, JSONObject formData) throws FormException {
String task = sr.getParameter("taskName");
String stage = sr.getParameter("stageName");
if ("".equals(task)) {
task = null;
}
if ("".equals(stage)) {
stage = null;
}
if (task == null && stage == null) {
return null;
}
return new PipelineProperty(task,
stage);
}
@Override
public PipelineProperty newInstance(StaplerRequest sr, JSONObject formData) throws FormException {
String task = sr.getParameter("taskName");
String stage = sr.getParameter("stageName");
boolean configEnabled = sr.getParameter("configEnabled") != null;
if (!configEnabled) {
return null;
}
if ("".equals(task)) {
task = null;
}
if ("".equals(stage)) {
stage = null;
}
if (task == null && stage == null) {
return null;
}
return new PipelineProperty(task, stage, configEnabled);
}
}
}
@@ -1,13 +1,13 @@
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
xmlns:t="/lib/hudson" xmlns:f="/lib/form">

<f:section title="Delivery Pipeline configuration">
<f:optionalBlock name="configEnabled" title="Delivery Pipeline configuration" inline="true" checked="${instance.configEnabled}">
<f:entry title="Stage Name" field="stageName">
<f:textbox name="stageName" value="${instance.getStageName()}"/>
</f:entry>

<f:entry title="Task Name" field="taskName">
<f:textbox name="taskName" value="${instance.getTaskName()}"/>
</f:entry>
</f:section>
</j:jelly>
</f:optionalBlock>
</j:jelly>
Expand Up @@ -279,7 +279,7 @@ public void testGetItemsAndContainsWithFolders() throws Exception {
@Test
public void testGetPipelines() throws Exception {
FreeStyleProject build = jenkins.createFreeStyleProject("build");
build.addProperty(new PipelineProperty("Build", "BuildStage"));
build.addProperty(new PipelineProperty("Build", "BuildStage", true));
List<DeliveryPipelineView.ComponentSpec> specs = new ArrayList<DeliveryPipelineView.ComponentSpec>();
specs.add(new DeliveryPipelineView.ComponentSpec("Comp", "build"));
DeliveryPipelineView view = new DeliveryPipelineView("Pipeline");
Expand Down Expand Up @@ -589,13 +589,13 @@ public void testTriggerManualNotAuthorized() throws Exception {
public void testRecursiveStages() throws Exception {

FreeStyleProject a = jenkins.createFreeStyleProject("A");
a.addProperty(new PipelineProperty("A", "A"));
a.addProperty(new PipelineProperty("A", "A", true));
FreeStyleProject b = jenkins.createFreeStyleProject("B");
b.addProperty(new PipelineProperty("B", "B"));
b.addProperty(new PipelineProperty("B", "B", true));
FreeStyleProject c = jenkins.createFreeStyleProject("C");
c.addProperty(new PipelineProperty("C", "C"));
c.addProperty(new PipelineProperty("C", "C", true));
FreeStyleProject d = jenkins.createFreeStyleProject("D");
d.addProperty(new PipelineProperty("D", "B"));
d.addProperty(new PipelineProperty("D", "B", true));

a.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(new BuildTriggerConfig("B", ResultCondition.SUCCESS, new ArrayList<AbstractBuildParameterFactory>())));
b.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(new BuildTriggerConfig("C", ResultCondition.SUCCESS, new ArrayList<AbstractBuildParameterFactory>())));
Expand Down
22 changes: 17 additions & 5 deletions src/test/java/se/diabol/jenkins/pipeline/PipelinePropertyTest.java
Expand Up @@ -80,6 +80,7 @@ public void testNewInstanceEmpty() throws Exception {
StaplerRequest request = Mockito.mock(StaplerRequest.class);
when(request.getParameter("taskName")).thenReturn("");
when(request.getParameter("stageName")).thenReturn("");
when(request.getParameter("configEnabled")).thenReturn("on");
assertNull(d.newInstance(request, null));
}

Expand All @@ -90,6 +91,7 @@ public void testNewInstanceNull() throws Exception {
StaplerRequest request = Mockito.mock(StaplerRequest.class);
when(request.getParameter("taskName")).thenReturn(null);
when(request.getParameter("stageName")).thenReturn(null);
when(request.getParameter("configEnabled")).thenReturn("on");
assertNull(d.newInstance(request, null));
}

Expand All @@ -100,12 +102,22 @@ public void testNewInstanceTaskNull() throws Exception {
StaplerRequest request = Mockito.mock(StaplerRequest.class);
when(request.getParameter("taskName")).thenReturn(null);
when(request.getParameter("stageName")).thenReturn("Stage");
when(request.getParameter("configEnabled")).thenReturn("on");
PipelineProperty p = d.newInstance(request, null);
assertNotNull(p);
assertNull(p.getTaskName());
assertEquals("Stage", p.getStageName());
assertEquals(true, p.getConfigEnabled());
}

@Test
@WithoutJenkins
public void testNewInstanceTaskNullDisabled() throws Exception {
PipelineProperty.DescriptorImpl d = new PipelineProperty.DescriptorImpl();
StaplerRequest request = Mockito.mock(StaplerRequest.class);
when(request.getParameter("configEnabled")).thenReturn(null);
assertNull(d.newInstance(request, null));
}

@Test
@WithoutJenkins
Expand All @@ -114,10 +126,12 @@ public void testNewInstanceBothSet() throws Exception {
StaplerRequest request = Mockito.mock(StaplerRequest.class);
when(request.getParameter("taskName")).thenReturn("Task");
when(request.getParameter("stageName")).thenReturn("Stage");
when(request.getParameter("configEnabled")).thenReturn("on");
PipelineProperty p = d.newInstance(request, null);
assertNotNull(p);
assertEquals("Task", p.getTaskName());
assertEquals("Stage", p.getStageName());
assertEquals(true, p.getConfigEnabled());
}

@Test
Expand All @@ -127,7 +141,7 @@ public void testDoAutoCompleteStageName() throws Exception {
FreeStyleProject build2 = jenkins.createFreeStyleProject("build2");
jenkins.createFreeStyleProject("build3");
build2.addProperty(new PipelineProperty());
build.addProperty(new PipelineProperty("Build", "Build"));
build.addProperty(new PipelineProperty("Build", "Build", true));


AutoCompletionCandidates c1 = d.doAutoCompleteStageName("B");
Expand All @@ -138,8 +152,6 @@ public void testDoAutoCompleteStageName() throws Exception {

AutoCompletionCandidates c3 = d.doAutoCompleteStageName(null);
assertEquals(c3.getValues().size(), 0);


}

@Test
Expand All @@ -151,8 +163,8 @@ public void testGetStageNames() throws Exception {
Set<String> stageNames = PipelineProperty.getStageNames();
assertNotNull(stageNames);
assertEquals(0, stageNames.size());
build1.addProperty(new PipelineProperty(null, "Build"));
build2.addProperty(new PipelineProperty(null, "QA"));
build1.addProperty(new PipelineProperty(null, "Build", true));
build2.addProperty(new PipelineProperty(null, "QA", true));

stageNames = PipelineProperty.getStageNames();
assertNotNull(stageNames);
Expand Down
40 changes: 20 additions & 20 deletions src/test/java/se/diabol/jenkins/pipeline/domain/PipelineTest.java
Expand Up @@ -59,7 +59,7 @@ public void testExtractPipelineEmptyPropertyAndNullProperty() throws Exception {
assertEquals("job", pipeline.getStages().get(0).getName());
assertEquals("job", pipeline.getStages().get(0).getTasks().get(0).getName());

job.addProperty(new PipelineProperty("", ""));
job.addProperty(new PipelineProperty("", "", true));

pipeline = Pipeline.extractPipeline("Pipeline", job);
assertEquals(1, pipeline.getStages().size());
Expand All @@ -74,12 +74,12 @@ public void testExtractPipeline() throws Exception {
FreeStyleProject deploy = jenkins.createFreeStyleProject("deploy");
FreeStyleProject test = jenkins.createFreeStyleProject("test");

compile.addProperty(new PipelineProperty("Compile", "Build"));
compile.addProperty(new PipelineProperty("Compile", "Build", true));
compile.save();

deploy.addProperty(new PipelineProperty("Deploy", "Deploy"));
deploy.addProperty(new PipelineProperty("Deploy", "Deploy", true));
deploy.save();
test.addProperty(new PipelineProperty("Test", "Test"));
test.addProperty(new PipelineProperty("Test", "Test", true));
test.save();

compile.getPublishersList().add(new BuildTrigger("test", false));
Expand Down Expand Up @@ -117,13 +117,13 @@ public void testExtractPipeline() throws Exception {
@Test
public void testExtractSimpleForkJoinPipeline() throws Exception {
FreeStyleProject build = jenkins.createFreeStyleProject("build");
build.addProperty(new PipelineProperty(null, "build"));
build.addProperty(new PipelineProperty(null, "build", true));
FreeStyleProject deploy1 = jenkins.createFreeStyleProject("deploy1");
deploy1.addProperty(new PipelineProperty(null, "CI"));
deploy1.addProperty(new PipelineProperty(null, "CI", true));
FreeStyleProject deploy2 = jenkins.createFreeStyleProject("deploy2");
deploy2.addProperty(new PipelineProperty(null, "CI"));
deploy2.addProperty(new PipelineProperty(null, "CI", true));
FreeStyleProject deploy3 = jenkins.createFreeStyleProject("deploy3");
deploy3.addProperty(new PipelineProperty(null, "QA"));
deploy3.addProperty(new PipelineProperty(null, "QA", true));

build.getPublishersList().add(new BuildTrigger("deploy1,deploy2", false));
deploy1.getPublishersList().add(new BuildTrigger("deploy3", false));
Expand All @@ -142,12 +142,12 @@ public void testExtractSimpleForkJoinPipeline() throws Exception {
@Test
public void testExtractPipelineWithSubProjects() throws Exception {
FreeStyleProject build = jenkins.createFreeStyleProject("build");
build.addProperty(new PipelineProperty("Build", "Build"));
build.addProperty(new PipelineProperty("Build", "Build", true));
FreeStyleProject sonar = jenkins.createFreeStyleProject("sonar");
sonar.addProperty(new PipelineProperty("Sonar", "Build"));
sonar.addProperty(new PipelineProperty("Sonar", "Build", true));

FreeStyleProject deploy = jenkins.createFreeStyleProject("deploy");
deploy.addProperty(new PipelineProperty("Deploy", "QA"));
deploy.addProperty(new PipelineProperty("Deploy", "QA", true));


build.getBuildersList().add(new TriggerBuilder(new BlockableBuildTriggerConfig("sonar", new BlockingBehaviour("never", "never", "never"), null)));
Expand Down Expand Up @@ -270,8 +270,8 @@ public void testAggregatedStageWithTwoManualTasks() throws Exception {
FreeStyleProject build = jenkins.createFreeStyleProject("build");
FreeStyleProject ci1 = jenkins.createFreeStyleProject("ci1");
FreeStyleProject ci2 = jenkins.createFreeStyleProject("ci2");
ci1.addProperty(new PipelineProperty("ci1", "CI1"));
ci2.addProperty(new PipelineProperty("ci2", "CI1"));
ci1.addProperty(new PipelineProperty("ci1", "CI1", true));
ci2.addProperty(new PipelineProperty("ci2", "CI1", true));
build.getPublishersList().add(new BuildPipelineTrigger("ci1", null));
build.getPublishersList().add(new BuildPipelineTrigger("ci2", null));
jenkins.getInstance().rebuildDependencyGraph();
Expand Down Expand Up @@ -320,11 +320,11 @@ public void testAggregatedStageWithTwoManualTasks() throws Exception {
@Test
public void testCreatePipelineLatest() throws Exception {
FreeStyleProject build = jenkins.createFreeStyleProject("build");
build.addProperty(new PipelineProperty("", "Build"));
build.addProperty(new PipelineProperty("", "Build", true));
FreeStyleProject sonar = jenkins.createFreeStyleProject("sonar");
sonar.addProperty(new PipelineProperty("Sonar", "Build"));
sonar.addProperty(new PipelineProperty("Sonar", "Build", true));
FreeStyleProject deploy = jenkins.createFreeStyleProject("deploy");
deploy.addProperty(new PipelineProperty("Deploy", "CI"));
deploy.addProperty(new PipelineProperty("Deploy", "CI", true));
jenkins.getInstance().rebuildDependencyGraph();
jenkins.setQuietPeriod(0);

Expand Down Expand Up @@ -595,13 +595,13 @@ public void testGetPipelinesWhereRowsWillBeGambled() throws Exception {
public void testRecursiveStages() throws Exception {

FreeStyleProject a = jenkins.createFreeStyleProject("A");
a.addProperty(new PipelineProperty("A", "A"));
a.addProperty(new PipelineProperty("A", "A", true));
FreeStyleProject b = jenkins.createFreeStyleProject("B");
b.addProperty(new PipelineProperty("B", "B"));
b.addProperty(new PipelineProperty("B", "B", true));
FreeStyleProject c = jenkins.createFreeStyleProject("C");
c.addProperty(new PipelineProperty("C", "C"));
c.addProperty(new PipelineProperty("C", "C", true));
FreeStyleProject d = jenkins.createFreeStyleProject("D");
d.addProperty(new PipelineProperty("D", "B"));
d.addProperty(new PipelineProperty("D", "B", true));

a.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(new BuildTriggerConfig("B", ResultCondition.SUCCESS, new ArrayList<AbstractBuildParameterFactory>())));
b.getPublishersList().add(new hudson.plugins.parameterizedtrigger.BuildTrigger(new BuildTriggerConfig("C", ResultCondition.SUCCESS, new ArrayList<AbstractBuildParameterFactory>())));
Expand Down
Expand Up @@ -190,7 +190,7 @@ public void testFindStageForJob() {
public void testStageNameForMultiConfiguration() throws Exception {
MatrixProject project = jenkins.createMatrixProject("Multi");
project.setAxes(new AxisList(new Axis("axis", "foo", "bar")));
project.addProperty(new PipelineProperty("task", "stage"));
project.addProperty(new PipelineProperty("task", "stage", true));

Collection<MatrixConfiguration> configurations = project.getActiveConfigurations();

Expand Down
Expand Up @@ -123,7 +123,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
public void testTaskNameForMultiConfiguration() throws Exception {
MatrixProject project = jenkins.createMatrixProject("Multi");
project.setAxes(new AxisList(new Axis("axis", "foo", "bar")));
project.addProperty(new PipelineProperty("task", "stage"));
project.addProperty(new PipelineProperty("task", "stage", true));

Collection<MatrixConfiguration> configurations = project.getActiveConfigurations();

Expand Down

0 comments on commit 5cf6bd6

Please sign in to comment.