Skip to content
This repository has been archived by the owner on Sep 9, 2024. It is now read-only.

Commit

Permalink
Merge branch 'master' into JENKINS-21010
Browse files Browse the repository at this point in the history
Conflicts:
	src/main/webapp/pipe.js
  • Loading branch information
patbos committed Jan 14, 2014
2 parents 21cf965 + de4baa7 commit 4b75eb3
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 30 deletions.
108 changes: 92 additions & 16 deletions src/main/java/se/diabol/jenkins/pipeline/DeliveryPipelineView.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import java.io.IOException;
import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

@SuppressWarnings("UnusedDeclaration")
public class DeliveryPipelineView extends View {
Expand All @@ -60,10 +62,19 @@ public class DeliveryPipelineView extends View {
private int updateInterval = DEFAULT_INTERVAL;
private boolean showChanges = false;

private List<RegExpSpec> regexpFirstJobs;

@DataBoundConstructor
public DeliveryPipelineView(String name, List<ComponentSpec> componentSpecs) {
public DeliveryPipelineView(String name) {
super(name);
this.componentSpecs = componentSpecs;
}

public List<RegExpSpec> getRegexpFirstJobs() {
return regexpFirstJobs;
}

public void setRegexpFirstJobs(List<RegExpSpec> regexpFirstJobs) {
this.regexpFirstJobs = regexpFirstJobs;
}

public boolean getShowAvatars() {
Expand Down Expand Up @@ -194,15 +205,19 @@ public String getLastUpdated() {
public List<Component> getPipelines() {
LOG.fine("Getting pipelines!");
List<Component> components = new ArrayList<Component>();
for (ComponentSpec componentSpec : componentSpecs) {
AbstractProject firstJob = ProjectUtil.getProject(componentSpec.getFirstJob(), getOwnerItemGroup());
Pipeline prototype = PipelineFactory.extractPipeline(componentSpec.getName(), firstJob);
List<Pipeline> pipelines = new ArrayList<Pipeline>();
if (showAggregatedPipeline) {
pipelines.add(PipelineFactory.createPipelineAggregated(prototype, getOwnerItemGroup()));
if (componentSpecs != null) {
for (ComponentSpec componentSpec : componentSpecs) {
AbstractProject firstJob = ProjectUtil.getProject(componentSpec.getFirstJob(), getOwnerItemGroup());
components.add(getComponent(componentSpec.getName(), firstJob, showAggregatedPipeline));
}
}
if (regexpFirstJobs != null) {
for (RegExpSpec regexp : regexpFirstJobs) {
Map<String, AbstractProject> matches = ProjectUtil.getProjects(regexp.getRegexp());
for (Map.Entry<String, AbstractProject> entry : matches.entrySet()) {
components.add(getComponent(entry.getKey(), entry.getValue(), showAggregatedPipeline));
}
}
pipelines.addAll(PipelineFactory.createPipelineLatest(prototype, noOfPipelines, getOwnerItemGroup()));
components.add(new Component(componentSpec.getName(), pipelines));
}
if (getSorting() != null && !getSorting().equals(NONE_SORTER)) {
ComponentComparatorDescriptor comparatorDescriptor = ComponentComparator.all().find(sorting);
Expand All @@ -214,18 +229,39 @@ public List<Component> getPipelines() {
return components;
}

private Component getComponent(String name, AbstractProject firstJob, boolean showAggregatedPipeline) {
Pipeline prototype = PipelineFactory.extractPipeline(name, firstJob);
List<Pipeline> pipelines = new ArrayList<Pipeline>();
if (showAggregatedPipeline) {
pipelines.add(PipelineFactory.createPipelineAggregated(prototype, getOwnerItemGroup()));
}
pipelines.addAll(PipelineFactory.createPipelineLatest(prototype, noOfPipelines, getOwnerItemGroup()));
return new Component(name, pipelines);
}

@Override
public Collection<TopLevelItem> getItems() {
List<TopLevelItem> result = new ArrayList<TopLevelItem>();
for (ComponentSpec componentSpec : componentSpecs) {
Set<AbstractProject> projects = new HashSet<AbstractProject>();
if (componentSpecs != null) {
for (ComponentSpec componentSpec : componentSpecs) {
projects.add(ProjectUtil.getProject(componentSpec.getFirstJob(), getOwnerItemGroup()));
}
}
if (regexpFirstJobs != null) {
for (RegExpSpec regexp : regexpFirstJobs) {
Map<String, AbstractProject> projectMap = ProjectUtil.getProjects(regexp.getRegexp());
projects.addAll(projectMap.values());
}

AbstractProject project = ProjectUtil.getProject(componentSpec.getFirstJob(), getOwnerItemGroup());
Collection<AbstractProject<?, ?>> projects = ProjectUtil.getAllDownstreamProjects(project).values();
for (AbstractProject<?, ?> abstractProject : projects) {
}
for (AbstractProject project : projects) {
Collection<AbstractProject<?, ?>> downstreamProjects = ProjectUtil.getAllDownstreamProjects(project).values();
for (AbstractProject<?, ?> abstractProject : downstreamProjects) {
result.add(getItem(abstractProject.getName()));
}

}

return result;
}

Expand All @@ -237,6 +273,9 @@ public boolean contains(TopLevelItem item) {
@Override
protected void submit(StaplerRequest req) throws IOException, ServletException, Descriptor.FormException {
req.bindJSON(this, req.getSubmittedForm());
componentSpecs = req.bindJSONToList(ComponentSpec.class, req.getSubmittedForm().get("componentSpecs"));
regexpFirstJobs = req.bindJSONToList(RegExpSpec.class, req.getSubmittedForm().get("regexpFirstJobs"));

}

@Override
Expand All @@ -247,7 +286,6 @@ public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOExcep

@Extension
public static class DescriptorImpl extends ViewDescriptor {

public ListBoxModel doFillNoOfColumnsItems(@AncestorInPath ItemGroup<?> context) {
ListBoxModel options = new ListBoxModel();
options.add("1", "1");
Expand Down Expand Up @@ -294,6 +332,44 @@ public String getDisplayName() {
}
}

public static class RegExpSpec extends AbstractDescribableImpl<RegExpSpec> {

private String regexp;

@DataBoundConstructor
public RegExpSpec(String regexp) {
this.regexp = regexp;
}

public String getRegexp() {
return regexp;
}

@Extension
public static class DescriptorImpl extends Descriptor<RegExpSpec> {

@Override
public String getDisplayName() {
return "RegExp";
}

public FormValidation doCheckRegexp(@QueryParameter String value) {
if (value != null) {
try {
Pattern pattern = Pattern.compile(value);
if (pattern.matcher("").groupCount() == 1) {
return FormValidation.ok();
} else {
return FormValidation.error("No capture group defined");
}
} catch (PatternSyntaxException e) {
return FormValidation.error("Syntax error in regular-expression pattern");
}
}
return FormValidation.ok();
}
}
}

public static class ComponentSpec extends AbstractDescribableImpl<ComponentSpec> {
private String name;
Expand Down
32 changes: 29 additions & 3 deletions src/main/java/se/diabol/jenkins/pipeline/util/ProjectUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import static com.google.common.collect.Maps.newLinkedHashMap;


public abstract class ProjectUtil {

private static final Logger LOG = Logger.getLogger(ProjectUtil.class.getName());

public static ListBoxModel fillAllProjects(ItemGroup<?> context) {
ListBoxModel options = new ListBoxModel();
for (AbstractProject<?, ?> p : Jenkins.getInstance().getAllItems(AbstractProject.class)) {
Expand Down Expand Up @@ -74,5 +79,26 @@ protected static List<AbstractProject> getSubProjects(AbstractProject project) {
return Jenkins.getInstance().getItem(name, context, AbstractProject.class);
}

public static Map<String, AbstractProject> getProjects(String regExp) {
try {
Pattern pattern = Pattern.compile(regExp);
Map<String, AbstractProject> result = new HashMap<String, AbstractProject>();
for (AbstractProject<?, ?> project : Jenkins.getInstance().getAllItems(AbstractProject.class)) {
Matcher matcher = pattern.matcher(project.getName());
if (matcher.find()) {
if (matcher.groupCount() >=1) {
String name = matcher.group(1);
result.put(name, project);
} else {
LOG.log(Level.WARNING, "Could not find match group");
}
}
}
return result;
} catch (PatternSyntaxException e) {
LOG.log(Level.WARNING, "Could not find projects on regular expression", e);
return Collections.emptyMap();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?jelly escape-by-default='true'?>
<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" xmlns:i="jelly:fmt">
<div>
<f:entry title="Regular Expression" field="regexp">
<f:textbox/>
</f:entry>
<div align="right">
<f:repeatableDeleteButton/>
</div>

</div>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div>
Find jenkins job matching regular expression<br/>
^build-(.+?)-project
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@
</f:section>

<f:section title="Pipelines">
<f:entry>
<f:repeatableProperty minimum="1" field="componentSpecs"/>
<f:entry title="Components">
<f:repeatableProperty minimum="0" field="componentSpecs"/>
</f:entry>
<f:entry title="Regular Expression">
<f:repeatableProperty minimum="0" field="regexpFirstJobs"/>
</f:entry>
</f:section>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

<div id="pipelineerror" class="pipelineerror"/>

<div id="pipeline-message" class="pipeline-message"/>

<j:forEach begin="1" end="${it.noOfColumns}" indexVar="i">
<script type="text/javascript">
pipelineContainers[${i-1}] = 'pipelines-${i}';
Expand Down
5 changes: 5 additions & 0 deletions src/main/webapp/pipe-fullscreen.css
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ div.pipelineerror {
display: none;
}

div.pipeline-message {
font-size: 20px;
text-align: center;
}

div.left {
float: left;
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/webapp/pipe.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ div.pipelineerror {
display: none;
}

div.pipeline-message {
font-size: 15px;
}

div.left {
float: left;
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/webapp/pipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ function refreshPipelines(data, divNames, errorDiv, view, showAvatars, showChang

var tasks = [];

if (data.pipelines.length == 0) {
Q("#pipeline-message").html('No pipelines configured or found. Please review the <a href="configure">configuration</a>')
}

for (var c = 0; c < data.pipelines.length; c++) {
var component = data.pipelines[c];
var html = "<section class='component'>";
Expand Down Expand Up @@ -162,6 +166,7 @@ function refreshPipelines(data, divNames, errorDiv, view, showAvatars, showChang
html = html + "</section>";
var index = 0;
Q("#" + divNames[c % divNames.length]).append(html);
Q("#pipeline-message").html('');
lastResponse = data;
equalheight(".stage");

Expand Down
Loading

0 comments on commit 4b75eb3

Please sign in to comment.