Skip to content
Permalink
Browse files
fixed JENKINS-18386, JENKINS-17597, JENKINS-17093, JENKINS-18399
  • Loading branch information
jacob_robertson committed Jun 28, 2013
1 parent 0af7e79 commit b10005a320585ed2fa03d6b06064fdb53fa0019c
@@ -0,0 +1,105 @@
package hudson.views;

import hudson.Extension;
import hudson.model.Descriptor;
import hudson.model.Job;
import hudson.model.Run;
import hudson.model.TopLevelItem;
import hudson.model.View;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Logger;

import org.kohsuke.stapler.DataBoundConstructor;

public class MostRecentJobsFilter extends ViewJobFilter {

private int maxToInclude;
private boolean checkStartTime;

private static final transient Logger log = Logger.getLogger("MostRecentJobsFilter");

@DataBoundConstructor
public MostRecentJobsFilter(int maxToInclude, boolean checkStartTime) {
this.maxToInclude = maxToInclude;
this.checkStartTime = checkStartTime;
}

@Override
public List<TopLevelItem> filter(List<TopLevelItem> added, List<TopLevelItem> all, View filteringView) {
List<TopLevelItem> filtered = new ArrayList<TopLevelItem>(added);

Collections.sort(filtered, new MostRecentJobsComparator());

// subList was causing null-pointer, not sure why.
// filtered = filtered.subList(0, maxToInclude);

int max = maxToInclude;
if (max > filtered.size()) {
max = filtered.size();
}
List<TopLevelItem> subList = new ArrayList<TopLevelItem>();
for (int i = 0; i < max; i++) {
subList.add(filtered.get(i));
}

return subList;
}

@SuppressWarnings("rawtypes")
private class MostRecentJobsComparator implements Comparator<TopLevelItem> {
public int compare(TopLevelItem i1, TopLevelItem i2) {
if (!(i1 instanceof Job)) {
return -1;
}
if (!(i2 instanceof Job)) {
return 1;
}
Job j1 = (Job) i1;
Job j2 = (Job) i2;

Long t1 = getTime(j1);
Long t2 = getTime(j2);

return t2.compareTo(t1);
}
}
@SuppressWarnings("rawtypes")
private long getTime(Job job) {
Run run = job.getLastBuild();
while (run != null) {
if (checkStartTime) {
return run.getTimeInMillis();
} else if (!run.isBuilding()) {
return run.getTimeInMillis() + run.getDuration();
} else {
run = run.getPreviousBuild();
}
}
return Long.MIN_VALUE;
}

@Extension
public static class DescriptorImpl extends Descriptor<ViewJobFilter> {
@Override
public String getDisplayName() {
return "Most Recent Jobs Filter";
}
@Override
public String getHelpFile() {
return "/plugin/view-job-filters/most-recent-help.html";
}
}

public boolean isCheckStartTime() {
return checkStartTime;
}

public int getMaxToInclude() {
return maxToInclude;
}

}
@@ -39,6 +39,7 @@

private boolean matchBuildsInProgress;
private boolean matchAllBuilds;
private int maxBuildsToMatch;

@DataBoundConstructor
public ParameterFilter(String includeExcludeTypeString,
@@ -47,6 +48,7 @@ public ParameterFilter(String includeExcludeTypeString,
String descriptionRegex,
boolean useDefaultValue,
boolean matchAllBuilds,
int maxBuildsToMatch,
boolean matchBuildsInProgress) {
super(includeExcludeTypeString);
this.nameRegex = nameRegex;
@@ -57,6 +59,7 @@ public ParameterFilter(String includeExcludeTypeString,
this.descriptionPattern = toPattern(descriptionRegex);
this.useDefaultValue = useDefaultValue;
this.matchAllBuilds = matchAllBuilds;
this.maxBuildsToMatch = maxBuildsToMatch;
this.matchBuildsInProgress = matchBuildsInProgress;
}

@@ -121,18 +124,20 @@ protected boolean matchesDefaultValue(Job job) {
@SuppressWarnings("unchecked")
protected boolean matchesBuildValue(Job job) {
boolean matched = false;
int count = 1;
Run run = job.getLastBuild();
while (run != null && !matched) {
// only match against the builds we care about
boolean isBuilding = run.isBuilding();
if (matchBuildsInProgress || !isBuilding) {
matched = matchesRun(run);
// now that we've checked one build, see if we should stop
if (!matchAllBuilds) {
if (!matchAllBuilds || (maxBuildsToMatch > 0 && count >= maxBuildsToMatch)) {
break;
}
}
run = run.getPreviousBuild();
count++;
}

return matched;
@@ -182,7 +187,14 @@ protected String getStringValue(ParameterDefinition definition) {
private boolean isValueMultiline(ParameterDefinition def) {
return (def instanceof ChoiceParameterDefinition);
}

protected String getStringValue(ParameterValue value) {
String sv = dogetStringValue(value);
System.out.println("getStringValue." + sv);
return sv;
}

protected String dogetStringValue(ParameterValue value) {
if (value instanceof StringParameterValue) {
return ((StringParameterValue) value).value;
} else if (value instanceof BooleanParameterValue) {
@@ -194,7 +206,8 @@ protected String getStringValue(ParameterValue value) {
String file = ((FileParameterValue) value).getOriginalFileName();
return file;
} else {
return null;
// means we can match on "null" - not sure that's useful though
return String.valueOf(value);
}
}

@@ -235,6 +248,10 @@ public boolean isMatchAllBuilds() {
return matchAllBuilds;
}

public int getMaxBuildsToMatch() {
return maxBuildsToMatch;
}

public boolean isMatchBuildsInProgress() {
return matchBuildsInProgress;
}
@@ -2,6 +2,7 @@

import hudson.Extension;
import hudson.model.AbstractItem;
import hudson.model.AbstractProject;
import hudson.model.Descriptor;
import hudson.model.SCMedItem;
import hudson.model.TopLevelItem;
@@ -24,7 +25,7 @@
public class RegExJobFilter extends AbstractIncludeExcludeJobFilter {

static enum ValueType {
NAME, DESCRIPTION, SCM, EMAIL, MAVEN, SCHEDULE
NAME, DESCRIPTION, SCM, EMAIL, MAVEN, SCHEDULE, NODE
}

transient private ValueType valueType;
@@ -54,7 +55,8 @@ Object readResolve() {
/**
* TODO this pattern works fine, but it may be better to provide this as a list of helpers.
*/
public List<String> getMatchValues(TopLevelItem item) {
@SuppressWarnings("rawtypes")
public List<String> getMatchValues(TopLevelItem item) {
List<String> values = new ArrayList<String>();
if (valueType == ValueType.DESCRIPTION) {
if (item instanceof AbstractItem) {
@@ -81,6 +83,11 @@ Object readResolve() {
// we do this split, because the spec may have multiple lines - especially including the comment
addSplitValues(values, scheduleValue);
}
} else if (valueType == ValueType.NODE) {
if (item instanceof AbstractProject) {
String node = ((AbstractProject) item).getAssignedLabelString();
values.add(node);
}
}
return values;
}
@@ -0,0 +1,10 @@
<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" xmlns:p="/lib/hudson/project">
<f:entry title="${%Number of Jobs To Include}">
<f:textbox name="maxToInclude" field="maxToInclude" />
</f:entry>
<f:entry title="${%Use job start time instead of completion time}">
<f:checkbox name="checkStartTime" field="checkStartTime"/>
</f:entry>
</j:jelly>
@@ -11,7 +11,9 @@
<f:checkbox name="useDefaultValue" field="useDefaultValue"/> ${%Match the configured default values instead of the actual value from last successful build}
</f:entry>
<f:entry>
<f:checkbox name="matchAllBuilds" field="matchAllBuilds"/> ${%Match against any build in the build history, not just the last build}
<f:checkbox name="matchAllBuilds" field="matchAllBuilds"/> ${%Match against this many previous builds} (${%blank or 0 for all}):
<st:nbsp />
<input type="text" name="maxBuildsToMatch" value="${instance.maxBuildsToMatch}" size="10" maxlength="10" />
</f:entry>
<f:entry>
<f:checkbox name="matchBuildsInProgress" field="matchBuildsInProgress"/> ${%Match against builds in progress}
@@ -12,6 +12,7 @@
<f:option value="EMAIL" selected="${instance.valueTypeString == 'EMAIL'}">${%Email recipients}</f:option>
<f:option value="MAVEN" selected="${instance.valueTypeString == 'MAVEN'}">${%Maven configuration}</f:option>
<f:option value="SCHEDULE" selected="${instance.valueTypeString == 'SCHEDULE'}">${%Job schedule}</f:option>
<f:option value="NODE" selected="${instance.valueTypeString == 'NODE'}">${%Node label expression}</f:option>
</select>
</f:entry>
<st:include page="config.jelly" class="hudson.views.AbstractIncludeExcludeJobFilter" optional="false"/>
@@ -27,14 +27,14 @@ public void testMatchesParameter() {
private void doTestMatchesParameter(String nameRegex, String valueRegex, String descRegex,
String name, String value, String desc, boolean expectMatched) {
ParameterFilter filter = new ParameterFilter(AbstractIncludeExcludeJobFilter.IncludeExcludeType.includeMatched.toString(),
nameRegex, valueRegex, descRegex, false, false, false);
nameRegex, valueRegex, descRegex, false, false, 0, false);
boolean matched = filter.matchesParameter(name, value, false, desc);
assertEquals(expectMatched, matched);
}

public void testBuildValue() throws Exception {
ParameterFilter filter = new ParameterFilter(AbstractIncludeExcludeJobFilter.IncludeExcludeType.includeMatched.toString(),
"N", "V1", "", true, false, false);
"N", "V1", "", true, false, 0, false);

FreeStyleProject proj = createFreeStyleProject("P1");

@@ -55,7 +55,7 @@ public void testBuildValue() throws Exception {


ParameterFilter filter2 = new ParameterFilter(AbstractIncludeExcludeJobFilter.IncludeExcludeType.includeMatched.toString(),
"N", "V1", "", false, false, false);
"N", "V1", "", false, false, 0, false);
// won't match, because it's not a build param
matches = filter2.matches(proj);
assertFalse(matches);

0 comments on commit b10005a

Please sign in to comment.