提交 ace3257d 编写于 作者: J jbq

Issue number: 763

Gracefully handle project deleted in SVN.  Had to make AbstractProject.disabled
field public, but we might want to find a more elegant solution for this.  I've
seen other fields public in Hudson, so I guess it's OK, but I'd rather put some
more setters everywhere...


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@4665 71c3de6d-444a-0410-be80-ed276b4c234a
上级 931a158b
......@@ -3,44 +3,46 @@ package hudson.model;
import hudson.FeedAdapter;
import hudson.FilePath;
import hudson.Launcher;
import hudson.search.SearchIndexBuilder;
import hudson.tasks.BuildTrigger;
import hudson.maven.MavenModule;
import hudson.model.Descriptor.FormException;
import hudson.model.Fingerprint.RangeSet;
import hudson.model.RunMap.Constructor;
import hudson.scm.ChangeLogSet;
import hudson.scm.ChangeLogSet.Entry;
import hudson.scm.NullSCM;
import hudson.scm.SCM;
import hudson.scm.SCMS;
import hudson.scm.ChangeLogSet.Entry;
import hudson.search.SearchIndexBuilder;
import hudson.tasks.BuildTrigger;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
import hudson.triggers.Triggers;
import hudson.util.EditDistance;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Vector;
import java.util.Set;
import java.util.Collections;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
/**
* Base implementation of {@link Job}s that build software.
*
......@@ -92,7 +94,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* True to suspend new builds.
*/
protected boolean disabled;
public boolean disabled;
/**
* Identifies {@link JDK} to be used.
......
......@@ -292,7 +292,7 @@ public class SubversionSCM extends SCM implements Serializable {
}
public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, final BuildListener listener, File changelogFile) throws IOException, InterruptedException {
List<String> externals = checkout(build.getTimestamp().getTime(),workspace,listener);
List<String> externals = checkout(build,workspace,listener);
if(externals==null)
return false;
......@@ -333,9 +333,14 @@ public class SubversionSCM extends SCM implements Serializable {
* if the operation failed. Otherwise the set of local workspace paths
* (relative to the workspace root) that has loaded due to svn:external.
*/
private List<String> checkout(Date timestamp, FilePath workspace, TaskListener listener) throws IOException, InterruptedException {
boolean isUpdatable = useUpdate && workspace.act(new IsUpdatableTask(this, listener));
return workspace.act(new CheckOutTask(this, timestamp, isUpdatable, listener));
private List<String> checkout(AbstractBuild build, FilePath workspace, TaskListener listener) throws IOException, InterruptedException {
if (projectDeleted(listener)) {
// Disable this project, see issue #763
build.getProject().disabled = true;
return null;
}
Boolean isUpdatable = useUpdate && workspace.act(new IsUpdatableTask(this, listener));
return workspace.act(new CheckOutTask(this, build.getTimestamp().getTime(), isUpdatable, listener));
}
private static class CheckOutTask implements FileCallable<List<String>> {
......@@ -487,7 +492,7 @@ public class SubversionSCM extends SCM implements Serializable {
* @param remoteUrl
* The target to run "svn info".
*/
private SVNInfo parseSvnInfo(SVNURL remoteUrl, ISVNAuthenticationProvider authProvider) throws SVNException {
private static SVNInfo parseSvnInfo(SVNURL remoteUrl, ISVNAuthenticationProvider authProvider) throws SVNException {
SVNWCClient svnWc = createSvnClientManager(authProvider).getWCClient();
return svnWc.doInfo(remoteUrl, SVNRevision.HEAD, SVNRevision.HEAD);
}
......@@ -561,26 +566,28 @@ public class SubversionSCM extends SCM implements Serializable {
private final TaskListener listener;
private final ISVNAuthenticationProvider authProvider;
private final ModuleLocation[] locations;
IsUpdatableTask(SubversionSCM parent,TaskListener listener) {
this.authProvider = parent.getDescriptor().createAuthenticationProvider();
this.listener = listener;
this.locations = parent.getLocations();
}
public Boolean invoke(File ws, VirtualChannel channel) throws IOException {
for (ModuleLocation l : locations) {
String url = l.remote;
String moduleName = l.local;
File module = new File(ws,moduleName).getCanonicalFile(); // canonicalize to remove ".." and ".". See #474
if(!module.exists()) {
listener.getLogger().println("Checking out a fresh workspace because "+module+" doesn't exist");
return false;
}
try {
SvnInfo svnInfo = new SvnInfo(parseSvnInfo(module, authProvider));
SVNInfo svnkitInfo = parseSvnInfo(module, authProvider);
SvnInfo svnInfo = new SvnInfo(svnkitInfo);
if(!svnInfo.url.equals(url)) {
listener.getLogger().println("Checking out a fresh workspace because the workspace is not "+url);
return false;
......@@ -596,6 +603,26 @@ public class SubversionSCM extends SCM implements Serializable {
private static final long serialVersionUID = 1L;
}
/**
* Returns true if the project does not exist in SVN anymore
*/
public boolean projectDeleted(TaskListener listener) {
for (ModuleLocation l : locations) {
String url = l.remote;
try {
ISVNAuthenticationProvider authProvider = getDescriptor().createAuthenticationProvider();
// This will throw an SVNException if the remote path does not exist anymore
parseSvnInfo(SVNURL.parseURIDecoded(url), authProvider);
} catch (SVNException e) {
// issue #763 Gracefully handle project deleted in SVN
listener.getLogger().println("Project does not exist anymore in SVN: " + url);
e.printStackTrace(listener.error(e.getMessage()));
return true;
}
}
return false;
}
public boolean pollChanges(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener) throws IOException, InterruptedException {
AbstractBuild lastBuild = (AbstractBuild) project.getLastBuild();
if(lastBuild==null) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册