提交 7741f96b 编写于 作者: K Kohsuke Kawaguchi

fix up next/previous build links

上级 eec63feb
......@@ -62,6 +62,7 @@ import hudson.util.Iterators;
import hudson.util.LogTaskListener;
import hudson.util.VariableResolver;
import jenkins.model.Jenkins;
import jenkins.model.lazy.AbstractLazyLoadRunMap.Direction;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
......@@ -170,6 +171,26 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
return getParent();
}
private boolean previousBuildComputed, nextBuildComputed;
@Override
public R getPreviousBuild() {
if (previousBuild==null && !previousBuildComputed) {
previousBuild = getParent().builds.search(number-1, Direction.DESC);
previousBuildComputed = true;
}
return previousBuild;
}
@Override
public R getNextBuild() {
if (nextBuild==null && !nextBuildComputed) {
nextBuild = getParent().builds.search(number+1, Direction.ASC);
nextBuildComputed = true;
}
return nextBuild;
}
/**
* Returns a {@link Slave} on which this build was done.
*
......
......@@ -160,7 +160,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* {@link Run#getPreviousBuild()}
*/
@Restricted(NoExternalUse.class)
protected transient /*almost final*/ RunMap<R> builds = new RunMap<R>();
protected transient RunMap<R> builds = new RunMap<R>();
/**
* The quiet period. Null to delegate to the system default.
......@@ -269,9 +269,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
super.onLoad(parent, name);
if (this.builds==null)
this.builds = new RunMap<R>();
this.builds.load(this,new Constructor<R>() {
this.builds = new RunMap<R>(getBuildDir(),new Constructor<R>() {
public R create(File dir) throws IOException {
return loadBuild(dir);
}
......
......@@ -44,7 +44,6 @@ import hudson.model.Descriptor.FormException;
import hudson.model.listeners.RunListener;
import hudson.model.listeners.SaveableListener;
import hudson.security.PermissionScope;
import jenkins.model.Jenkins.MasterComputer;
import hudson.search.SearchIndexBuilder;
import hudson.security.ACL;
import hudson.security.AccessControlled;
......@@ -640,10 +639,11 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
// a new build is in progress
BallColor baseColor;
if(previousBuild==null)
RunT pb = getPreviousBuild();
if(pb==null)
baseColor = BallColor.GREY;
else
baseColor = previousBuild.getIconColor();
baseColor = pb.getIconColor();
return baseColor.anime();
}
......@@ -747,10 +747,10 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
* Returns the last build that was actually built - i.e., skipping any with Result.NOT_BUILT
*/
public RunT getPreviousBuiltBuild() {
RunT r=previousBuild;
RunT r=getPreviousBuild();
// in certain situations (aborted m2 builds) r.getResult() can still be null, although it should theoretically never happen
while( r!=null && (r.getResult() == null || r.getResult()==Result.NOT_BUILT) )
r=r.previousBuild;
r=r.getPreviousBuild();
return r;
}
......@@ -758,9 +758,9 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
* Returns the last build that didn't fail before this build.
*/
public RunT getPreviousNotFailedBuild() {
RunT r=previousBuild;
RunT r=getPreviousBuild();
while( r!=null && r.getResult()==Result.FAILURE )
r=r.previousBuild;
r=r.getPreviousBuild();
return r;
}
......@@ -768,9 +768,9 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
* Returns the last failed build before this build.
*/
public RunT getPreviousFailedBuild() {
RunT r=previousBuild;
RunT r=getPreviousBuild();
while( r!=null && r.getResult()!=Result.FAILURE )
r=r.previousBuild;
r=r.getPreviousBuild();
return r;
}
......@@ -779,9 +779,9 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
* @since 1.383
*/
public RunT getPreviousSuccessfulBuild() {
RunT r=previousBuild;
RunT r=getPreviousBuild();
while( r!=null && r.getResult()!=Result.SUCCESS )
r=r.previousBuild;
r=r.getPreviousBuild();
return r;
}
......
......@@ -62,10 +62,23 @@ public final class RunMap<R extends Run<?,R>> extends AbstractLazyLoadRunMap<R>
// patch up next/previous build link
/**
* @deprecated
* Use {@link #RunMap(File, Constructor)}.
*/
public RunMap() {
super(null); // will be set later
}
/**
* @param cons
* Used to create new instance of {@link Run}.
*/
public RunMap(File baseDir, Constructor cons) {
super(baseDir);
this.cons = cons;
}
@Override
public boolean remove(R run) {
if(run.nextBuild!=null)
......@@ -179,8 +192,10 @@ public final class RunMap<R extends Run<?,R>> extends AbstractLazyLoadRunMap<R>
* Job that owns this map.
* @param cons
* Used to create new instance of {@link Run}.
* @deprecated
* Use {@link #RunMap(File, Constructor)}
*/
public synchronized void load(Job job, Constructor<R> cons) {
public void load(Job job, Constructor<R> cons) {
this.cons = cons;
initBaseDir(job.getBuildDir());
}
......
......@@ -94,7 +94,6 @@ public abstract class AbstractLazyLoadRunMap<R> extends AbstractMap<Integer,R> i
*/
private File dir;
@Restricted(NoExternalUse.class) // for now
protected AbstractLazyLoadRunMap(File dir) {
this.dir = dir;
initBaseDir(dir);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册